﻿using System;
using System.CodeDom;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel.Design;
using System.Configuration;
using System.Data;
using System.Diagnostics;
using System.IO;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;
using System.Workflow.Activities;
using System.Workflow.Activities.Rules;
using System.Workflow.ComponentModel;
using System.Workflow.ComponentModel.Compiler;
using System.Workflow.ComponentModel.Design;
using System.Workflow.ComponentModel.Serialization;
using System.Workflow.Runtime;
using System.Xml;
using System.Xml.Serialization;
using OpenComposite.Base;
using OpenComposite.Base.Collections;
using OpenComposite.EII.Designer.Workflow;
using OpenComposite.EII.Interfaces;
using OpenComposite.EII.Repository;
using OpenComposite.Mapper;
using OpenComposite.Workflow;
using OpenComposite.Workflow.Services;
using System.CodeDom.Compiler;
using System.Windows.Forms;
using Microsoft.CSharp;
using OpenComposite.HumanActivity.Contracts.Participants;

namespace OpenComposite.EII.CodeGenerators
{
	internal class WorkflowCodeGenerator : IMemberCreationCodeService
	{
		#region Initialization
		internal WorkflowCodeGenerator(
			Repository.Workflow workflow, IServiceProvider serviceProvider, ITaskListService taskList)
		{
			if ( workflow == null ) throw new ArgumentNullException("workflow");
			_taskList = taskList;

			this.Workflow = workflow;
			this.WorkflowName = workflow.Name;

			this.RuleIDs = workflow.GetRuleIDs();
			this.RuleConstantIDs = new List<int>();

			if ( serviceProvider != null ) {
				_serviceContainer = new ServiceContainer(serviceProvider);
			} else {
				_serviceContainer = new ServiceContainer(workflow);
			}

			init();
		}
		internal WorkflowCodeGenerator(
			Repository.Workflow workflow, IServiceProvider serviceProvider)
			: this(workflow, serviceProvider, null)
		{
		}
		private void init()
		{
			#region create the code beside code compile unit
			ccuBeside = new CodeCompileUnit();
			ccuBeside.ReferencedAssemblies.Add("System.Workflow.Activities");

			CodeNamespace ns = new CodeNamespace(this.Namespace);
			ns.Imports.Add(new CodeNamespaceImport("System"));
			ns.Imports.Add(new CodeNamespaceImport("System.ComponentModel"));
			ns.Imports.Add(new CodeNamespaceImport("System.ComponentModel.Design"));
			ns.Imports.Add(new CodeNamespaceImport("System.Workflow.ComponentModel.Design"));
			ns.Imports.Add(new CodeNamespaceImport("System.Workflow.ComponentModel"));
			ns.Imports.Add(new CodeNamespaceImport("System.Workflow.ComponentModel.Serialization"));
			ns.Imports.Add(new CodeNamespaceImport("System.Workflow.ComponentModel.Compiler"));
			ns.Imports.Add(new CodeNamespaceImport("System.Drawing"));
			ns.Imports.Add(new CodeNamespaceImport("System.Collections"));
			ns.Imports.Add(new CodeNamespaceImport("System.Workflow.Activities"));
			ns.Imports.Add(new CodeNamespaceImport("System.Workflow.ComponentModel"));
			ns.Imports.Add(new CodeNamespaceImport("System.Workflow.Runtime"));

			ccuBeside.Namespaces.Add(ns);

			_ctdBeside = new CodeTypeDeclaration(this.ClassName);
			if ( this.Workflow.Type == WorkflowType.Business_Process ||
				 this.Workflow.Type == WorkflowType.Mashup_Horizontal ) {
				_ctdBeside.BaseTypes.Add(typeof(OpenComposite.Workflow.HorizontalWorkflowActivity));
			} else {
				_ctdBeside.BaseTypes.Add(typeof(System.Workflow.Activities.SequentialWorkflowActivity));
			}
			_ctdBeside.BaseTypes.Add(this.OrchestrationInterfaceName);
			_ctdBeside.IsPartial = true;
			_ctdBeside.Attributes = MemberAttributes.Public;

			ns.Types.Add(_ctdBeside);
			#endregion

			ccuLogActivities = new CodeCompileUnit();
			ccuServices = new CodeCompileUnit();
			ccuMapping = new CodeCompileUnit();
			ccuRules = new CodeCompileUnit();
			ccuData = new CodeCompileUnit();
			ccuContracts = new CodeCompileUnit();
			ccuInterface = new CodeCompileUnit();
			ccuLocalService = new CodeCompileUnit();
			ccuHostService = new CodeCompileUnit();
			ccuWFInterface = new CodeCompileUnit();
			ccuXaml = new CodeCompileUnit();

			#region initialize service container and type provider
			TypeProvider typeProvider = new TypeProvider(_serviceContainer);

			typeProvider.AddCodeCompileUnit(this.CodeBeside);
			typeProvider.AddCodeCompileUnit(this.CodeContracts);
			typeProvider.AddCodeCompileUnit(this.CodeData);
			typeProvider.AddCodeCompileUnit(this.CodeHostService);
			typeProvider.AddCodeCompileUnit(this.CodeInterface);
			typeProvider.AddCodeCompileUnit(this.CodeLogicalActivities);
			typeProvider.AddCodeCompileUnit(this.CodeMapping);
			typeProvider.AddCodeCompileUnit(this.CodeRules);
			typeProvider.AddCodeCompileUnit(this.CodeServices);
			typeProvider.AddCodeCompileUnit(this.CodeWorkflowInterface);

			typeProvider.AddAssemblyReference(typeof(System.EventHandler).Assembly.Location);
			typeProvider.AddAssemblyReference(typeof(System.ComponentModel.AttributeCollection).Assembly.Location);
			typeProvider.AddAssemblyReference(typeof(System.Workflow.ComponentModel.CompositeActivity).Assembly.Location);
			typeProvider.AddAssemblyReference(typeof(System.Workflow.Activities.SequentialWorkflowActivity).Assembly.Location);
			typeProvider.AddAssemblyReference(typeof(System.Runtime.Serialization.XsdDataContractImporter).Assembly.Location);
			typeProvider.AddAssemblyReference(typeof(System.ServiceModel.EndpointAddress).Assembly.Location);
			typeProvider.AddAssemblyReference(typeof(System.Web.Services.WebService).Assembly.Location);
			typeProvider.AddAssemblyReference(typeof(System.Xml.XmlDocument).Assembly.Location);
			typeProvider.AddAssemblyReference(typeof(OpenComposite.Base.Structures.RepositoryInformationAttribute).Assembly.Location);
			typeProvider.AddAssemblyReference(typeof(OpenComposite.Workflow.LogicalEPActivity).Assembly.Location);

			_serviceContainer.AddService(typeof(ITypeProvider), typeProvider, false);
			#endregion

			#region initialize Xoml Code
			string nameSpace = this.Namespace;
			string typeName = this.ClassName;

			this.CodeXaml.Namespaces.Add
				(Helpers.GenerateCodeFromXomlDocument
					(Helpers.GetRootActivity(this.Workflow), _serviceContainer, ref nameSpace, ref typeName));


			this.Workflow.Name = typeName;
			this.Workflow.ExtendedProperties.NamespaceCode = nameSpace;
			try {
				typeProvider.AddCodeCompileUnit(this.CodeXaml);
			} catch {
				try {
					typeProvider.RefreshCodeCompileUnit(this.CodeXaml, new EventHandler(this.refreshCCU));
				} catch { }
			}
			#endregion

			#region initialize MembeCreationService
			_memberCreation = new MemberCreationService(_serviceContainer, this);
			_serviceContainer.AddService(typeof(IMemberCreationService), _memberCreation);
			#endregion
		}
		#endregion

		#region Internal Members

		#region Properties

		/// <summary>
		/// Gets or private sets the workflow.
		/// </summary>
		/// <value>The workflow.</value>
		internal Repository.Workflow Workflow { get; private set; }
		/// <summary>
		/// Gets or private sets the list of rule ids.
		/// </summary>
		/// <value>The rule ids.</value>
		internal List<int> RuleIDs { get; private set; }
		/// <summary>
		/// Gets or private sets the list of rule constant ids.
		/// </summary>
		/// <value>The rule constant ids.</value>
		internal List<int> RuleConstantIDs { get; private set; }

		/// <summary>
		/// Gets or sets a value indicating whether [show error message box].
		/// </summary>
		/// <value>
		/// 	<c>true</c> if [show error message box]; otherwise, <c>false</c>.
		/// </value>
		public bool ShowErrorMessageBox { get; set; }

		/// <summary>
		/// Gets a value indicating whether [generate data contract].
		/// </summary>
		/// <value>
		/// 	<c>true</c> if [generate data contract]; otherwise, <c>false</c>.
		/// </value>
		public bool GenerateDataContract
		{
			get { return this.Workflow.GenerateDataContract; }
		}

		/// <summary>
		/// Gets the default namespace.
		/// </summary>
		/// <value>The default namespace.</value>
		internal string DefaultNamespace
		{
			get
			{
				return "OpenComposite.Orchestration";
			}
		}
		/// <summary>
		/// Gets or sets the namespace.
		/// </summary>
		/// <value>The namespace.</value>
		internal string Namespace
		{
			get
			{
				Debug.Assert(!string.IsNullOrEmpty(this.WorkflowName));
				if ( !string.IsNullOrEmpty(this.WorkflowName) ) {
					return string.Format("{0}.{1}", this.DefaultNamespace, this.WorkflowName);
				} else {
					return this.DefaultNamespace;
				}
			}
		}
		/// <summary>
		/// Gets the namespace data.
		/// </summary>
		/// <value>The namespace data.</value>
		internal string NamespaceData
		{
			get { return string.Format("{0}.{1}", this.Namespace, "Data"); }
		}
		/// <summary>
		/// Gets the namespace rules.
		/// </summary>
		/// <value>The namespace rules.</value>
		internal string NamespaceRules
		{
			get { return this.DefaultNamespace; }
		}

		/// <summary>
		/// Gets or sets the name of the workflow.
		/// </summary>
		/// <value>The name of the workflow.</value>
		internal string WorkflowName { get; set; }
		/// <summary>
		/// Gets or sets the name of the class.
		/// </summary>
		/// <value>The name of the class.</value>
		internal string ClassName
		{
			get
			{
				Debug.Assert(!string.IsNullOrEmpty(this.WorkflowName));
				return ( !string.IsNullOrEmpty(this.WorkflowName) ? this.WorkflowName : "Orchestration1" );
			}
		}
		/// <summary>
		/// Gets the full name of the class.
		/// </summary>
		/// <value>The full name of the class.</value>
		internal string FullClassName
		{
			get
			{
				if ( string.IsNullOrEmpty(this.Namespace) )
					return this.ClassName;
				else
					return string.Format("{0}.{1}", this.Namespace, this.ClassName);
			}
		}
		/// <summary>
		/// Gets the name of the interface.
		/// </summary>
		/// <value>The name of the interface.</value>
		internal string InterfaceName
		{
			get { return "I" + this.ClassName; }
		}
		/// <summary>
		/// Gets the name of the callback interface.
		/// </summary>
		/// <value>The name of the callback interface.</value>
		internal string CallbackInterfaceName
		{
			get { return "I" + this.ClassName + "Callback"; }
		}
		/// <summary>
		/// Gets the name of the orchestration interface.
		/// </summary>
		/// <value>The name of the orchestration interface.</value>
		internal string OrchestrationInterfaceName
		{
			get { return "I" + this.ClassName + "Orchestration"; }
		}

		#region Compile Units
		internal CodeCompileUnit CodeXaml { get { return ccuXaml; } }
		internal CodeCompileUnit CodeBeside { get { return ccuBeside; } }
		internal CodeCompileUnit CodeContracts { get { return ccuContracts; } }
		internal CodeCompileUnit CodeData { get { return ccuData; } }
		internal CodeCompileUnit CodeHostService { get { return ccuHostService; } }
		internal CodeCompileUnit CodeInterface { get { return ccuInterface; } }
		internal CodeCompileUnit CodeLocalService { get { return ccuLocalService; } }
		internal CodeCompileUnit CodeLogicalActivities { get { return ccuLogActivities; } }
		internal CodeCompileUnit CodeMapping { get { return ccuMapping; } }
		internal CodeCompileUnit CodeRules { get { return ccuRules; } }
		internal CodeCompileUnit CodeServices { get { return ccuServices; } }
		internal CodeCompileUnit CodeWorkflowInterface { get { return ccuWFInterface; } }
		#endregion

		#endregion

		#region Methods
		/// <summary>
		/// Generates the code.
		/// </summary>
		internal void GenerateCode()
		{
			#region get services

			IDesignerHost host = (IDesignerHost)this.GetService(typeof(IDesignerHost));
			RepositoryService repSvc = (RepositoryService)this.GetService(typeof(RepositoryService));
			ITaskListService taskList = (ITaskListService)this.GetService(typeof(ITaskListService));

			if ( repSvc == null ) throw new NullReferenceException("Repository Service missing.");

			#endregion

			#region initialize code generation
			Deployment deployment = null;
			if ( host != null ) {
				deployment = new Deployment(host);
			} else {
				deployment = new Deployment(_serviceContainer);
			}
			WaitMouse wait = new WaitMouse();
			DesignerTransaction trans = null;
			if ( host != null ) trans = host.CreateTransaction();

			if ( taskList != null ) taskList.Clear(this.Workflow, cTaskListSourceNameGenerate);

			Dictionary<int, string> dicWebServiceIDEPConfigName = new Dictionary<int, string>();
			#endregion

			try {

				#region initialize workflow and compile units
				this.Workflow.ExtendedProperties.FullName = this.FullClassName;
				Activity main;
				if ( this.Workflow.Type == WorkflowType.Business_Process ||
					this.Workflow.Type == WorkflowType.Mashup_Horizontal ) {
					if ( host != null ) {
						main = host.RootComponent as HorizontalWorkflowActivity;
					} else {
						main = Helpers.GetRootActivity(this.Workflow) as HorizontalWorkflowActivity;
					}
					ccuBeside.Namespaces[0].Types[0].BaseTypes.Clear();
					ccuBeside.Namespaces[0].Types[0].BaseTypes.Add(typeof(HorizontalWorkflowActivity));
				} else {
					if ( host != null ) {
						main = host.RootComponent as SequentialWorkflowActivity;
					} else {
						main = Helpers.GetRootActivity(this.Workflow) as SequentialWorkflowActivity;
					}
					ccuBeside.Namespaces[0].Types[0].BaseTypes.Clear();
					ccuBeside.Namespaces[0].Types[0].BaseTypes.Add(typeof(SequentialWorkflowActivity));
				}
				ccuBeside.Namespaces[0].Types[0].BaseTypes.Add(this.OrchestrationInterfaceName);

				main.Name = this.Workflow.Name;
				main.SetValue(WorkflowMarkupSerializer.XClassProperty, this.FullClassName);
				ServiceGenerationType currentSvcGenType;
				TypeProvider typeProvider = GetService(typeof(ITypeProvider)) as TypeProvider;
				MemberCreationService memberCreation = GetService(typeof(IMemberCreationService)) as MemberCreationService;
				if ( typeProvider == null )
					throw new NullReferenceException("TypeProvider missing.");
				if ( memberCreation == null )
					throw new NullReferenceException("MemberCreationService missing.");

				initCompileUnits();
				RefreshAllCode();

				// save Workflow Informations
				this.Workflow.ExtendedProperties.NamespaceCode = this.Namespace;
				this.Workflow.ExtendedProperties.FullName = this.FullClassName;
				this.Workflow.ExtendedProperties.InterfaceName = this.InterfaceName;
				#endregion

				#region initialize config file
				string pathTmp = Path.Combine(Path.Combine(Path.GetTempPath(), "OpenComposite"), this.ClassName);
				if ( !Directory.Exists(pathTmp) ) Directory.CreateDirectory(pathTmp);
				string configFile = Path.Combine(pathTmp, "app.config");
				if ( File.Exists(configFile) ) File.Delete(configFile);

				Configuration machineConfig = ConfigurationManager.OpenMachineConfiguration();
				ExeConfigurationFileMap fileMap = new ExeConfigurationFileMap();
				fileMap.ExeConfigFilename = configFile;
				fileMap.MachineConfigFilename = machineConfig.FilePath;

				configuration = ConfigurationManager
					.OpenMappedExeConfiguration(fileMap, ConfigurationUserLevel.None);
				configuration.NamespaceDeclared = true;
				configuration.Save(ConfigurationSaveMode.Minimal, true);
				#endregion

				#region initialize simulation
				addSimulationPropertiesToWFCodeBeside();
				#endregion

				#region init process dataset for human activities
				// init process dataset for human activities
				initProcessDS();

				if ( this.Workflow.Type == WorkflowType.Mashup ||
					 this.Workflow.Type == WorkflowType.Mashup_Horizontal ) {
					generateMashupForm();
				}
				#endregion

				#region add rules
				int[] ruleids = this.RuleIDs.ToArray();
				foreach ( int id in ruleids ) {
					Repository.RepositoryBusinessRule brule = null;
					try {
						brule = repSvc.GetItem(ItemType.BRule, id, true) as Repository.RepositoryBusinessRule;
					} catch ( RepositoryItemDeletedException ) {
						this.RuleIDs.Remove(id);
						continue;
					}
					if ( brule != null ) {
						foreach ( int ruleid in brule.GetUsedBusinessRuleIDs() ) {
							if ( !this.RuleIDs.Contains(ruleid) ) {
								Repository.RepositoryBusinessRule rule = null;
								try {
									rule = repSvc.GetItem(ItemType.BRule, ruleid, true) as Repository.RepositoryBusinessRule;
								} catch ( RepositoryItemDeletedException ) {
									continue;
								}
								if ( rule != null ) AddRuleToCode(rule);
							}
						}
						List<int> usedconsts = brule.GetUsedRuleConstantIDs();
						if ( usedconsts != null ) {
							foreach ( int constid in usedconsts ) {
								if ( !this.RuleConstantIDs.Contains(constid) )
									this.RuleConstantIDs.Add(constid);
							}
						}
						AddRuleToCode(brule);

						if ( brule.ExtendedProperties.RuleType ==
								RepositoryBusinessRule.BusinessRuleType.GenericRule ) {
							#region update rule methods call
							CodeMethodInvokeExpression methinvoke =
								deployment.GetBusinessRuleInvokeExpression(this.CodeRules,
								new CodeThisReferenceExpression(), brule, this.NamespaceRules);
							RuleDefinitions ruleDef = getRuleDefinitions();
							foreach ( RuleCondition rulecond in ruleDef.Conditions ) {
								foreach ( var result in brule.Results.Split(';') ) {
									RuleExpressionCondition ruleexp = rulecond as RuleExpressionCondition;
									if ( ruleexp != null && ruleexp.Name == ( brule.Name + "_" + result ) ) {
										CodeBinaryOperatorExpression binopexpr =
											ruleexp.Expression as CodeBinaryOperatorExpression;
										binopexpr.Left = methinvoke;
										setRuleDefinitions(ruleDef);
										if ( host != null && host.RootComponent is CompositeActivity ) {
											( (CompositeActivity)host.RootComponent )
												.SetValue(RuleDefinitions.RuleDefinitionsProperty, ruleDef);
										}
										break;
									}
								}
							}
							#endregion
						}
					}
				}
				// IF ConfigurationLevel == UtilizeConfiguration THEN create constructor
				generateRuleConstantsCode(repSvc);

				refreshTypeProvider(ref typeProvider, ref ccuRules);

				#endregion

				#region initialize process variables
				addProcessVariablesToCodeBeside();
				#endregion

				#region get all activities
				List<Activity> activities = new List<Activity>();
				if ( host != null && host.RootComponent is CompositeActivity ) {
					activities = Helpers.GetNestedActivities((CompositeActivity)host.RootComponent);
				} else {
					activities = Helpers.GetNestedActivities(Helpers.GetRootActivity(this.Workflow) as CompositeActivity);
				}
				if ( activities.Count == 0 ) throw new Exception("No Activities available.");
				#endregion

				#region initialize code snippets
				// remove deleted code snippets
				try {
					List<Repository.Workflow.MethodCodeSnippet> methods = this.Workflow.ExtendedProperties.MethodCodeSnippets;

					for ( int i = methods.Count - 1; i >= 0; i-- ) {
						Repository.Workflow.MethodCodeSnippet method = methods[i];
						if ( string.IsNullOrEmpty(method.ActivityName) ) {
							CodeMemberMethod meth = deployment.getMethodFromCode(ccuBeside, this.FullClassName, method.MethodName);
							if ( meth != null ) {
								if ( ccuBeside.Namespaces.Count > 0 && ccuBeside.Namespaces[0].Types.Count > 0 ) {
									ccuBeside.Namespaces[0].Types[0].Members.Remove(meth);
								}
							}
							methods.Remove(method);
							continue;
						} else {
							bool found = false;
							foreach ( Activity activity in activities ) {
								if ( activity.Name == method.ActivityName ) {
									found = true;
									break;
								}
							}
							if ( !found ) {
								CodeMemberMethod meth = deployment.getMethodFromCode(this.ccuBeside, this.FullClassName, method.MethodName);
								if ( meth != null ) {
									if ( ccuBeside.Namespaces.Count > 0 && ccuBeside.Namespaces[0].Types.Count > 0 ) {
										ccuBeside.Namespaces[0].Types[0].Members.Remove(meth);
									}
								}
								methods.Remove(method);

								continue;
							}
						}
					}
				} catch { }

				addMethodCodeSnippetsToCodeBeside(deployment);
				#endregion

				#region generate proxy
				if ( this.Workflow.BuildType == WorkflowBuildType.WCF_WindowsForm ) {
					generateProxyForMashup(deployment);
				} else if ( this.Workflow.BuildType == WorkflowBuildType.WCF_IIS ) {
					generateProxyForWCFService(deployment);
				}
				#endregion

				#region set variables
				bool foundFirstAct = false;
				//bool hasStartAct = false;
				this.Workflow.ExtendedProperties.HasHumanActivity = false;
				#endregion

				foreach ( Activity act in activities ) {

					#region IF not fount first activity
					if ( !foundFirstAct ) {
						if ( act is WebServiceInputActivity || act is HandleExternalEventActivity ||
							 act is LogicalInputActivity ) {
							foundFirstAct = true;
							//hasStartAct = true;
							if ( act is LogicalInputActivity ) {
								LogicalInputActivity lia = (LogicalInputActivity)act;
								LogicalActivity la = repSvc.GetItem<LogicalActivity>(lia.LogicalActivityId);
								if ( la != null ) {
									WorkflowEvent we = repSvc.GetItem<WorkflowEvent>(la.WorkflowEventID);
									this.Workflow.StartName = we.Name;
									this.Workflow.StartDescription = we.Description;
									this.Workflow.InputBusinessObject = we.BusinessObject;
								}
							}
						} else if ( !( act is CompositeActivity ) ) {
							foundFirstAct = true;
							//hasStartAct = false;
						}
					}
					#endregion

					try {
						// if logical activity
						if ( act is LogicalCapabilityActivity ) {
							#region generate LogicalCapabilityActivity code
							bool doContinue;

							currentSvcGenType = generateLogicalCapabilityActivityCode(act, host, repSvc, deployment, dicWebServiceIDEPConfigName, ref typeProvider, out doContinue);

							if ( doContinue ) continue;
							#endregion
						} else if ( act is DataAggregatorActivity ) {
							#region generate DataAggregatorActivity code
							bool doContinue;
							generateDataAggregatorActivityCode(act, host, repSvc, deployment, ref typeProvider, out doContinue);
							if ( doContinue ) continue;
							#endregion
						} else if ( act is RuleEvaluatorActivity ) {
							#region generate RuleEvaluatorActivity code
							bool doContinue;
							generateRuleEvaluatorActivity(act, host, repSvc, deployment, ref typeProvider, out doContinue);
							if ( doContinue ) continue;
							#endregion
						} else if ( act is LogicalMethodCallActivity ) {
							#region LogicalMethodCallActivity
							initLogicalMethodCallActivity(host, repSvc, typeProvider, act);
							#endregion
						} else if ( act is LogicalInputActivity ) {
							#region LogicalInputActivity
							initLogicalInputActivity(host, repSvc, typeProvider, act);
							#endregion
						} else if ( act is NotificationActivity ) {
							#region NotificationActivity
							createNotificationActivity(act, host, repSvc);
							#endregion
						} else if ( act is ExtendedCodeActivity ) {
							#region ExtendedCodeActivity
							createExtendedCodeActivity(act, host);
							#endregion
						}
					} catch ( Exception ex ) {

						#region display error
						if ( taskList == null ) {
							string msg = string.Format(
								"Error while generating code for activity '{0}'.{1}{1}{2}",
								act.Name, Environment.NewLine, ex.Message);
							//MessageBox.Show(msg, "Generate Logical Activities Code", MessageBoxButtons.OK, MessageBoxIcon.Error);
							throw new Exception(msg, ex);
						} else {
							string msg = string.Format("Activity '{0}': {1}", act.Name, ex.Message);
							if ( ex.InnerException != null && !string.IsNullOrEmpty(ex.InnerException.Message) ) {
								msg += Environment.NewLine + "Inner Exception: " + ex.InnerException.Message;
							}
							taskList.Add(this.Workflow, TaskItemType.Error, TaskStatus.None, ex, msg, cTaskListSourceNameGenerate);
						}
						#endregion

					}

				}
				#region add empty private class to data code to prevent not existing data namespace
				if ( ccuData.Namespaces.Count > 0 &&
					ccuData.Namespaces[0].Types.Count == 0 ) {
					ccuData.Namespaces[0].Types.Add(new CodeTypeDeclaration("__empty"));
				}
				#endregion

				#region save human activities
				saveHumanActivityProcess();
				//_dsHAProc = null;
				#endregion

				#region verify rule parameter resolve
				bool showRebuildRulesMsg = false;
				BindingListEx<Repository.Workflow.RuleParameterResolve> lstRPR =
					new BindingListEx<OpenComposite.EII.Repository.Workflow.RuleParameterResolve>();
				int[] ruleidarray = this.RuleIDs.ToArray();
				foreach ( int idRule in ruleidarray ) {
					RepositoryBusinessRule rbr = repSvc.GetItem<RepositoryBusinessRule>(idRule);
					if ( rbr == null ) {
						this.RuleIDs.Remove(idRule);
					} else {
						BindingListEx<Repository.Workflow.RuleParameterResolve> lRuleRPR = rbr.GetRuleParameterResolveList();
						foreach ( var item in lRuleRPR ) {
							if ( item.ParameterID <= 0 ) {
								showRebuildRulesMsg = true;
								continue;
							}
							if ( !existsNounInResolveList(lstRPR, item.ParameterID) ) {
								lstRPR.Add(item);
							}
						}
					}
				}
				BindingListEx<Repository.Workflow.RuleParameterResolve> lstRPRExisting = this.Workflow.ExtendedProperties.WorkflowVariables;
				foreach ( var rprnew in lstRPR ) {
					if ( !existsNounInResolveList(lstRPRExisting, rprnew.ParameterID) ) {
						// search for an item with the same name but no ParameterID
						Repository.Workflow.RuleParameterResolve rprexisting = getRPRByName(lstRPRExisting, rprnew.ParameterName);
						if ( rprexisting != null ) {
							// set id to existing item
							rprexisting.ParameterID = rprnew.ParameterID;
						} else {
							// add new item to existing list
							lstRPRExisting.Add(rprnew);
						}
					}
				}
				foreach ( OpenComposite.EII.Repository.Workflow.RuleParameterResolve rpr in this.Workflow.ExtendedProperties.WorkflowVariables.ToArray() ) {
					if ( rpr.ParameterID <= 0 ) {
						showRebuildRulesMsg = true;
					} else {
						if ( !existsNounInResolveList(lstRPR, rpr.ParameterID) ) {
							this.Workflow.ExtendedProperties.WorkflowVariables.Remove(rpr);
							continue;
						}
					}
					bool resolvepropexists = false;
					foreach ( CodeTypeMember codeMember in ccuBeside.Namespaces[0].Types[0].Members ) {
						CodeMemberProperty codeProp = codeMember as CodeMemberProperty;
						if ( codeProp != null &&
							 rpr.ParameterResolve != null && rpr.ParameterResolve.StartsWith(codeProp.Name) ) {
							resolvepropexists = true;
							break;
						}
					}
					if ( !resolvepropexists ) {
						rpr.ParameterResolve = null;
					}
					Type propType = OpenComposite.EII.Helpers.GetDotNetTypeOfDataTypeString(rpr.ParameterDataType);
					memberCreation.CreatePropertyForRuleParameterResolution(
						this.FullClassName, rpr.ParameterName, propType,
						rpr.ParameterResolve);

					// change property type to nullable if type is a valuetype
					if ( propType.IsValueType ) {
						Type nullableType = typeof(Nullable<>);
						propType = nullableType.MakeGenericType(propType);
					}
					addPropertyToInterface(_ctdWFInterface, propType, rpr.ParameterName, true, true);
				}
				if ( taskList != null && showRebuildRulesMsg ) {
					string msg = string.Format("Please open and save all used rule policies to initialize the new vocabulary assignment.");
					taskList.Add(this.Workflow, TaskItemType.Task, TaskStatus.Todo, null, msg, cTaskListSourceNameGenerate);
				}
				#endregion

				#region save configuration
				// save Configuration
				configuration.Save(ConfigurationSaveMode.Minimal, true);
				ConfigXmlDocument xdConfig = new ConfigXmlDocument();
				xdConfig.Load(configuration.FilePath);
				this.Workflow.ExtendedProperties.ConfigurationString = xdConfig.OuterXml;
				#endregion

				#region disable wait cursor
				if ( wait != null ) {
					wait.Dispose();
					wait = null;
				}
				#endregion

				#region commit transaction
				if ( trans != null ) trans.Commit();
				#endregion

				#region write source code to workflow
				generateSourceCode();
				#endregion

			} catch ( Exception ex ) {

				#region disable wait cursor
				if ( wait != null ) {
					wait.Dispose();
					wait = null;
				}
				#endregion

				#region cancel and rollback transaction
				if ( trans != null ) trans.Cancel();
				#endregion

				#region display error
				if ( taskList == null ) {
					//MessageBox.Show(ex.Message, "Generate Logical Activities Code", MessageBoxButtons.OK, MessageBoxIcon.Error);
					throw ex;
				} else {
					string msg = string.Format("Workflow '{0}': {1}", this.Workflow.Name, ex.Message);
					taskList.Add(this.Workflow, TaskItemType.Error, TaskStatus.None, ex, msg, cTaskListSourceNameGenerate);
				}
				#endregion

			} finally {

			}

			#region refresh type provider
			RefreshAllCode();
			#endregion
		}

		/// <summary>
		/// Refreshes all code.
		/// </summary>
		internal void RefreshAllCode()
		{
			TypeProvider typeProvider = GetService(typeof(ITypeProvider)) as TypeProvider;
			refreshTypeProvider(ref typeProvider, ref ccuContracts);
			refreshTypeProvider(ref typeProvider, ref ccuData);
			refreshTypeProvider(ref typeProvider, ref ccuLogActivities);
			refreshTypeProvider(ref typeProvider, ref ccuMapping);
			refreshTypeProvider(ref typeProvider, ref ccuRules);
			refreshTypeProvider(ref typeProvider, ref ccuServices);
			refreshTypeProvider(ref typeProvider, ref ccuInterface);
			refreshTypeProvider(ref typeProvider, ref ccuLocalService);
		}

		/// <summary>
		/// Compiles the code.
		/// </summary>
		/// <returns>The WorkflowCompilerResults.</returns>
		internal WorkflowCompilerResults CompileCode()
		{
			ITaskListService taskList = (ITaskListService)this.GetService(typeof(ITaskListService));
			if ( this.Workflow == null || string.IsNullOrEmpty(this.Workflow.XOML) ) {
				return null; // EXIT
			}

			WorkflowCompilerResults results = null;
			string wfname = RepositoryService.GetIdentifier(this.Workflow.Name);
			string pathTmp = Path.Combine(Path.Combine(Path.GetTempPath(), "OpenComposite"), wfname);

			if ( !Directory.Exists(pathTmp) ) Directory.CreateDirectory(pathTmp);
			if ( taskList != null ) taskList.Clear(this.Workflow, "");

			try {
				StringBuilder errors = new StringBuilder();
				using ( new OpenComposite.Base.WaitMouse() ) {
					List<string> files = this.saveFiles(pathTmp);

					// Check for code beside file and rules file

					WorkflowCompiler compiler = new WorkflowCompiler();
					WorkflowCompilerParameters parameters = new WorkflowCompilerParameters();
					parameters.ReferencedAssemblies.Add(typeof(System.EventHandler).Assembly.Location);
					parameters.ReferencedAssemblies.Add(typeof(System.ComponentModel.AttributeCollection).Assembly.Location);
					parameters.ReferencedAssemblies.Add(typeof(System.Workflow.ComponentModel.CompositeActivity).Assembly.Location);
					parameters.ReferencedAssemblies.Add(typeof(System.Workflow.Activities.SequentialWorkflowActivity).Assembly.Location);
					parameters.ReferencedAssemblies.Add(typeof(OpenComposite.Workflow.LogicalEPActivity).Assembly.Location);
					parameters.ReferencedAssemblies.Add(typeof(System.Runtime.Serialization.XsdDataContractImporter).Assembly.Location);
					parameters.ReferencedAssemblies.Add(typeof(System.ServiceModel.EndpointAddress).Assembly.Location);
					parameters.ReferencedAssemblies.Add(typeof(System.Web.Services.WebService).Assembly.Location);
					parameters.ReferencedAssemblies.Add(typeof(System.Xml.XmlDocument).Assembly.Location);
					parameters.ReferencedAssemblies.Add(typeof(OpenComposite.Base.Structures.RepositoryInformationAttribute).Assembly.Location);
					parameters.ReferencedAssemblies.Add(typeof(System.Configuration.ConfigurationManager).Assembly.Location);

					parameters.GenerateInMemory = true;

					string rulesFile = "";
					foreach ( string file in files ) {
						if ( file.ToLower().EndsWith(".rules") )
							rulesFile = file;
					}
					files.Remove(rulesFile);
					if ( File.Exists(rulesFile) ) {
						// adding the rules file to the resources
						if ( parameters.CompilerOptions != null && parameters.CompilerOptions.Length > 0 ) parameters.CompilerOptions += " ";
						string resources = "/resource:\"" + rulesFile + "\"," + this.Namespace + "." + this.ClassName + "." + "rules";
						parameters.CompilerOptions += resources;
					}
					// Compile the workflow
					results = compiler.Compile(parameters, files.ToArray());

					Directory.Delete(pathTmp, true);

					foreach ( CompilerError compilerError in results.Errors ) {
						string file = Path.GetFileName(compilerError.FileName);
						errors.AppendLine(string.Format("{0}: Line {1}: {2}", file, compilerError.Line, compilerError.ErrorText));
					}
					parameters.TempFiles.Delete();
					results.TempFiles.Delete();
				}
				if ( errors.Length != 0 ) {
					if ( taskList == null ) {
						MessageBox.Show(errors.ToString(), "Compile Orchestration", MessageBoxButtons.OK, MessageBoxIcon.Error);
					} else {
						if ( results != null && results.Errors != null ) {
							foreach ( CompilerError compilerError in results.Errors ) {
								string file = Path.GetFileName(compilerError.FileName);
								taskList.Add(
									this.Workflow,
									compilerError.IsWarning ? TaskItemType.Warning : TaskItemType.Error,
									TaskStatus.None, compilerError,
									string.Format("{0}: Line {1}: {2}", file, compilerError.Line, compilerError.ErrorText),
									"");
							}
						} else {
							taskList.Add(this.Workflow, TaskItemType.Error, TaskStatus.None, null, errors.ToString(), cTaskListSourceNameCompile);
						}
					}
				} else {
					if ( taskList == null ) {
						MessageBox.Show(
							"Orchestration compiled successfully."/* Compiled assembly: \n" + results.CompiledAssembly.GetName()*/
							, "Compile Orchestration", MessageBoxButtons.OK, MessageBoxIcon.Information);
					} else {
						taskList.Add(this.Workflow, TaskItemType.Message, TaskStatus.None, null, "Orchestration compiled successfully.", cTaskListSourceNameCompile);
					}
				}
			} catch ( Exception ex ) {
				MessageBox.Show(ex.Message, "Compile Error!", MessageBoxButtons.OK, MessageBoxIcon.Error);
			} finally {
			}
			return results;
		}

		#endregion

		#endregion

		#region Private Members

		#region Constants
		private const string cTaskListSourceNameGenerate = "Generate Workflow";
		private const string cTaskListSourceNameSave = "Save Workflow";
		private const string cTaskListSourceNameCompile = "Compile Workflow";
		#endregion

		#region Fields
		private string xoml = string.Empty;
		private StringBuilder tempRulesStream = null;

		private ServiceContainer _serviceContainer;
		private ITaskListService _taskList;

		// we maintain two code compile units: 1 for code beside file and 1 for xaml file
		private CodeCompileUnit ccuBeside = null;
		private CodeTypeDeclaration _ctdBeside = null;
		private CodeMemberMethod _methodBesideInit = null;
		private CodeMemberField _fieldBesideMapping = null;
		private CodeMemberField _fieldBesideRules = null;
		private CodeMemberProperty _propBesideMapping = null;
		private CodeMemberProperty _propBesideRules = null;

		private CodeCompileUnit ccuXaml = null;

		// addional code compile units for special classes

		private CodeCompileUnit ccuLogActivities;
		private CodeTypeDeclaration _ctdLogActs;

		private CodeCompileUnit ccuServices;
		private CodeTypeDeclaration _ctdServices;

		private CodeCompileUnit ccuMapping;
		private CodeTypeDeclaration _ctdMapping;
		private CodeConstructor _ctorMapping;

		private CodeCompileUnit ccuRules;
		private CodeTypeDeclaration _ctdRules;

		private CodeCompileUnit ccuData;
		private CodeCompileUnit ccuContracts;

		private CodeCompileUnit ccuInterface;
		private CodeTypeDeclaration _ctdInterface;
		private CodeTypeDeclaration _ctdInterfaceCallback;

		private CodeCompileUnit ccuLocalService;
		private CodeNamespace _nsLocalService;
		private CodeTypeDeclaration _ctdLocalService;
		private CodeTypeDeclaration _ctdLocalInterface;

		private CodeCompileUnit ccuHostService;
		private CodeTypeDeclaration _ctdHostService;

		private CodeCompileUnit ccuWFInterface;
		private CodeTypeDeclaration _ctdWFInterface;

		private MemberCreationService _memberCreation;

		private Configuration configuration;
		#endregion

		#region Methods

		#region get services
		private object GetService(Type serviceType)
		{
			if ( serviceType == typeof(ITaskListService) && _taskList != null ) {
				return _taskList;
			}
			return _serviceContainer.GetService(serviceType);
		}
		#endregion

		#region initialize
		private void initCompileUnits()
		{
			#region initialize code beside
			bool configMapping = this.Workflow.IsConfigurable ||
								 this.Workflow.IsConfigurable;
			bool configRules = this.Workflow.IsConfigurable;
			if ( configMapping || configRules ) {
				if ( _methodBesideInit == null ) {
					// add Initialize override
					_methodBesideInit = new CodeMemberMethod();
					_methodBesideInit.Attributes = MemberAttributes.Family | MemberAttributes.Override;
					_methodBesideInit.StartDirectives.Add(new CodeRegionDirective(CodeRegionMode.Start, "Initialization"));
					_methodBesideInit.EndDirectives.Add(new CodeRegionDirective(CodeRegionMode.End, "Initialization"));
					_methodBesideInit.Name = "Initialize";
					_methodBesideInit.Parameters.Add(
						new CodeParameterDeclarationExpression(typeof(IServiceProvider), "provider"));
					if ( configMapping ) {
						_methodBesideInit.Statements.Add(
							new CodeAssignStatement(
								new CodeFieldReferenceExpression(
									new CodeThisReferenceExpression(), "_mapping"),
								new CodeObjectCreateExpression(this.Namespace + ".Mapping")));
					}
					if ( configRules ) {
						_methodBesideInit.Statements.Add(
							new CodeAssignStatement(
								new CodeFieldReferenceExpression(
									new CodeThisReferenceExpression(), "_rules"),
								new CodeObjectCreateExpression(this.NamespaceRules + ".Rules")));
					}
					_methodBesideInit.Statements.Add(new CodeCommentStatement("call base initialization"));
					_methodBesideInit.Statements.Add(
						new CodeMethodInvokeExpression(
							new CodeBaseReferenceExpression(),
							"Initialize",
							new CodeArgumentReferenceExpression("provider")));
					_ctdBeside.Members.Add(_methodBesideInit);
				}
			} else if ( _methodBesideInit != null ) {
				_ctdBeside.Members.Remove(_methodBesideInit);
				_methodBesideInit = null;
			}
			// add fields and properties for Rules and Mapping class
			if ( configMapping && _fieldBesideMapping == null ) {
				_fieldBesideMapping = new CodeMemberField(this.Namespace + ".Mapping", "_mapping");
				_ctdBeside.Members.Add(_fieldBesideMapping);
			} else if ( !configMapping && _fieldBesideMapping != null ) {
				_ctdBeside.Members.Remove(_fieldBesideMapping);
				_fieldBesideMapping = null;
			}
			if ( configRules && _fieldBesideRules == null ) {
				_fieldBesideRules = new CodeMemberField(this.NamespaceRules + ".Rules", "_rules");
				_ctdBeside.Members.Add(_fieldBesideRules);
			} else if ( !configRules && _fieldBesideRules != null ) {
				_ctdBeside.Members.Remove(_fieldBesideRules);
				_fieldBesideRules = null;
			}
			if ( configMapping && _propBesideMapping == null ) {
				_propBesideMapping = new CodeMemberProperty();
				_propBesideMapping.Attributes = MemberAttributes.Public | MemberAttributes.Final;
				_propBesideMapping.HasGet = true;
				_propBesideMapping.HasSet = false;
				_propBesideMapping.Type = new CodeTypeReference(this.Namespace + ".Mapping");
				_propBesideMapping.Name = "Mapping";
				_propBesideMapping.GetStatements.Add(
					new CodeMethodReturnStatement(
						new CodeFieldReferenceExpression(
							new CodeThisReferenceExpression(), "_mapping")));
				_ctdBeside.Members.Add(_propBesideMapping);
			} else if ( !configMapping && _propBesideMapping != null ) {
				_ctdBeside.Members.Remove(_propBesideMapping);
				_propBesideMapping = null;
			}
			if ( configRules && _propBesideRules == null ) {
				_propBesideRules = new CodeMemberProperty();
				_propBesideRules.Attributes = MemberAttributes.Public | MemberAttributes.Final;
				_propBesideRules.HasGet = true;
				_propBesideRules.HasSet = false;
				_propBesideRules.Type = new CodeTypeReference(this.NamespaceRules + ".Rules");
				_propBesideRules.Name = "Rules";
				_propBesideRules.GetStatements.Add(
					new CodeMethodReturnStatement(
						new CodeFieldReferenceExpression(
							new CodeThisReferenceExpression(), "_rules")));
				_ctdBeside.Members.Add(_propBesideRules);
			} else if ( !configRules && _propBesideRules != null ) {
				_ctdBeside.Members.Remove(_propBesideRules);
				_propBesideRules = null;
			}
			#endregion

			#region create logical activity class code compile unit
			ccuLogActivities.Namespaces.Clear();
			CodeNamespace nsLogAct = new CodeNamespace(this.Namespace);
			nsLogAct.Imports.Add(new CodeNamespaceImport("System"));
			nsLogAct.Imports.Add(new CodeNamespaceImport("System.Collections.Generic"));
			nsLogAct.Imports.Add(new CodeNamespaceImport("System.Text"));
			ccuLogActivities.Namespaces.Add(nsLogAct);
			_ctdLogActs = new CodeTypeDeclaration("LogicalActivities");
			_ctdLogActs.Attributes = MemberAttributes.Public;
			_ctdLogActs.CustomAttributes.Add(new CodeAttributeDeclaration(new CodeTypeReference(typeof(SerializableAttribute))));
			CodeConstructor ctorLogAct = new CodeConstructor();
			ctorLogAct.Attributes = MemberAttributes.Public;
			ctorLogAct.Parameters.Add(new CodeParameterDeclarationExpression(
										new CodeTypeReference(this.ClassName), "orchestration"));
			ctorLogAct.Statements.Add(
				new CodeAssignStatement(
					new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), "_orchestration"),
					new CodeArgumentReferenceExpression("orchestration")));
			_ctdLogActs.Members.Add(ctorLogAct);
			_ctdLogActs.Members.Add(new CodeMemberField(new CodeTypeReference(this.ClassName), "_orchestration"));
			nsLogAct.Types.Add(_ctdLogActs);
			#endregion

			#region create the service code compile unit
			ccuServices.Namespaces.Clear();
			CodeNamespace nsServices = new CodeNamespace(this.Namespace);
			nsServices.Imports.Add(new CodeNamespaceImport("System"));
			nsServices.Imports.Add(new CodeNamespaceImport("System.Collections.Generic"));
			nsServices.Imports.Add(new CodeNamespaceImport("System.Text"));
			nsServices.Imports.Add(new CodeNamespaceImport("System.Web.Services"));
			nsServices.Imports.Add(new CodeNamespaceImport("System.ServiceModel"));
			nsServices.Imports.Add(new CodeNamespaceImport("System.Diagnostics"));
			ccuServices.Namespaces.Add(nsServices);
			_ctdServices = new CodeTypeDeclaration("ServiceCalls");
			_ctdServices.Attributes = MemberAttributes.Public;
			_ctdServices.CustomAttributes.Add(new CodeAttributeDeclaration(new CodeTypeReference(typeof(SerializableAttribute))));
			// add contructor
			CodeConstructor ctorServices = new CodeConstructor();
			ctorServices.Attributes = MemberAttributes.Public;
			ctorServices.Parameters.Add(new CodeParameterDeclarationExpression(
										new CodeTypeReference(this.OrchestrationInterfaceName), "orchestration"));
			ctorServices.Statements.Add(
				new CodeAssignStatement(
					new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), "_orchestration"),
					new CodeArgumentReferenceExpression("orchestration")));
			_ctdServices.Members.Add(ctorServices);
			// add _orchestration member field
			_ctdServices.Members.Add(new CodeMemberField(new CodeTypeReference(this.OrchestrationInterfaceName), "_orchestration"));
			nsServices.Types.Add(_ctdServices);
			#endregion

			#region create mapping code compile unit
			ccuMapping.Namespaces.Clear();
			CodeNamespace nsMapping = new CodeNamespace(this.Namespace);
			nsMapping.Imports.Add(new CodeNamespaceImport("System"));
			nsMapping.Imports.Add(new CodeNamespaceImport("System.Collections.Generic"));
			nsMapping.Imports.Add(new CodeNamespaceImport("System.Text"));
			nsMapping.Imports.Add(new CodeNamespaceImport("System.Data"));
			nsMapping.Imports.Add(new CodeNamespaceImport("System.IO"));
			ccuMapping.Namespaces.Add(nsMapping);
			_ctdMapping = new CodeTypeDeclaration("Mapping");
			_ctdMapping.Attributes = MemberAttributes.Public;
			_ctdMapping.CustomAttributes.Add(new CodeAttributeDeclaration(new CodeTypeReference(typeof(SerializableAttribute))));
			nsMapping.Types.Add(_ctdMapping);
			if ( this.Workflow.IsConfigurable ||
				 this.Workflow.IsConfigurable ) {
				_ctorMapping = new CodeConstructor();
				_ctorMapping.Attributes = MemberAttributes.Public;
				_ctdMapping.Members.Add(_ctorMapping);
			} else {
				_ctorMapping = null;
			}
			#endregion

			#region create rules code compile unit
			ccuRules.Namespaces.Clear();
			CodeNamespace nsRules = new CodeNamespace(this.NamespaceRules);
			nsRules.Imports.Add(new CodeNamespaceImport("System"));
			nsRules.Imports.Add(new CodeNamespaceImport("System.Collections.Generic"));
			nsRules.Imports.Add(new CodeNamespaceImport("System.Text"));
			ccuRules.Namespaces.Add(nsRules);
			_ctdRules = new CodeTypeDeclaration("Rules");
			_ctdRules.Attributes = MemberAttributes.Public;
			_ctdRules.CustomAttributes.Add(new CodeAttributeDeclaration(new CodeTypeReference(typeof(SerializableAttribute))));
			nsRules.Types.Add(_ctdRules);
			#endregion

			#region create data code compile unit
			ccuData.Namespaces.Clear();
			CodeNamespace nsData = new CodeNamespace(this.NamespaceData);
			nsData.Imports.Add(new CodeNamespaceImport("System"));
			nsData.Imports.Add(new CodeNamespaceImport("System.Collections.Generic"));
			nsData.Imports.Add(new CodeNamespaceImport("System.Text"));
			nsData.Imports.Add(new CodeNamespaceImport("System.Xml.Serialization"));
			ccuData.Namespaces.Add(nsData);
			#endregion

			#region create contracts code compile unit
			ccuContracts.Namespaces.Clear();
			ccuContracts.AssemblyCustomAttributes.Clear();
			#endregion

			#region create orchestration interface compile unit
			ccuInterface.Namespaces.Clear();
			CodeNamespace nsInterface = new CodeNamespace(this.Namespace);
			nsInterface.Imports.Add(new CodeNamespaceImport("System"));
			nsInterface.Imports.Add(new CodeNamespaceImport("System.Collections.Generic"));
			nsInterface.Imports.Add(new CodeNamespaceImport("System.Text"));
			ccuInterface.Namespaces.Add(nsInterface);
			_ctdInterface = new CodeTypeDeclaration(this.InterfaceName);
			_ctdInterface.Attributes = MemberAttributes.Public;
			_ctdInterface.IsInterface = true;

			if ( this.Workflow.BuildType == WorkflowBuildType.WCF_IIS ||
				 this.Workflow.BuildType == WorkflowBuildType.WCF_WindowsForm ) {
				// IF WCF OR Mashup
				_ctdInterface.CustomAttributes.Add(
					new CodeAttributeDeclaration(
						new CodeTypeReference(typeof(ServiceContractAttribute)),
						new CodeAttributeArgument(
							"CallbackContract",
							new CodeTypeOfExpression(this.CallbackInterfaceName)),
						new CodeAttributeArgument(
							"Namespace",
							new CodePrimitiveExpression(
								string.IsNullOrEmpty(this.Workflow.XmlNamespace) ?
									"http://www.theopencomposite.com/canonical_document" :
									this.Workflow.XmlNamespace))));

				_ctdInterfaceCallback = new CodeTypeDeclaration(this.CallbackInterfaceName);
				_ctdInterfaceCallback.Attributes = MemberAttributes.Public;
				_ctdInterfaceCallback.IsInterface = true;
				_ctdInterfaceCallback.CustomAttributes.Add(
					new CodeAttributeDeclaration(
						new CodeTypeReference(typeof(ServiceContractAttribute)),
						new CodeAttributeArgument(
							"Namespace",
							new CodePrimitiveExpression(
								string.IsNullOrEmpty(this.Workflow.XmlNamespace) ?
									"http://www.theopencomposite.com/canonical_document" :
									this.Workflow.XmlNamespace))));

				nsInterface.Types.Add(_ctdInterfaceCallback);

			}
			nsInterface.Types.Add(_ctdInterface);
			#endregion

			#region create local service interface & implementation
			ccuLocalService.Namespaces.Clear();
			_nsLocalService = new CodeNamespace(this.Namespace);
			//_nsLocalService.Imports.Add(new CodeNamespaceImport("System"));
			//_nsLocalService.Imports.Add(new CodeNamespaceImport("System.Collections.Generic"));
			//_nsLocalService.Imports.Add(new CodeNamespaceImport("System.Text"));
			ccuLocalService.Namespaces.Add(_nsLocalService);

			// local interface
			_ctdLocalInterface = new CodeTypeDeclaration("I" + this.ClassName + Deployment.cProxy);
			_ctdLocalInterface.Attributes = MemberAttributes.Public;
			_ctdLocalInterface.IsInterface = true;
			_ctdLocalInterface.CustomAttributes.Add(
				new CodeAttributeDeclaration(
					new CodeTypeReference(typeof(ExternalDataExchangeAttribute))));
			_nsLocalService.Types.Add(_ctdLocalInterface);

			// local service
			_ctdLocalService = new CodeTypeDeclaration(this.ClassName + Deployment.cProxy);
			_ctdLocalService.Attributes = MemberAttributes.Public;
			_ctdLocalService.BaseTypes.Add(_ctdLocalInterface.Name);
			_nsLocalService.Types.Add(_ctdLocalService);
			#endregion

			#region create host service code compile unit
			ccuHostService.Namespaces.Clear();
			CodeNamespace nsHostEmpty = new CodeNamespace();
			nsHostEmpty.Imports.Add(new CodeNamespaceImport("System"));
			nsHostEmpty.Imports.Add(new CodeNamespaceImport("System.Collections.Generic"));
			nsHostEmpty.Imports.Add(new CodeNamespaceImport("System.Runtime.Serialization"));
			nsHostEmpty.Imports.Add(new CodeNamespaceImport("System.ServiceModel"));
			nsHostEmpty.Imports.Add(new CodeNamespaceImport("System.Text"));
			nsHostEmpty.Imports.Add(new CodeNamespaceImport(this.Namespace));
			nsHostEmpty.Imports.Add(new CodeNamespaceImport(this.NamespaceData));

			_ctdHostService = new CodeTypeDeclaration();
			_ctdHostService.Attributes = MemberAttributes.Public;
			_ctdHostService.BaseTypes.Add("I" + this.ClassName);
			_ctdHostService.CustomAttributes.Add(
				new CodeAttributeDeclaration(
					new CodeTypeReference(typeof(ServiceBehaviorAttribute)),
					new CodeAttributeArgument(
						"Namespace",
						new CodePrimitiveExpression(
							string.IsNullOrEmpty(this.Workflow.XmlNamespace) ?
							"http://www.theopencomposite.com/canonical_document" : this.Workflow.XmlNamespace)),
					new CodeAttributeArgument(
						"InstanceContextMode",
						new CodeFieldReferenceExpression(
							new CodeTypeReferenceExpression(typeof(InstanceContextMode)),
							"PerSession"))));
			_ctdHostService.Name = this.ClassName + "Service";

			nsHostEmpty.Types.Add(_ctdHostService);

			ccuHostService.Namespaces.Add(nsHostEmpty);
			#endregion

			#region create orchstration interface code compile unit
			// create namespace
			ccuWFInterface.Namespaces.Clear();
			CodeNamespace nsWFInterface = new CodeNamespace(this.Namespace);
			ccuWFInterface.Namespaces.Add(nsWFInterface);
			// create interface
			_ctdWFInterface = new CodeTypeDeclaration(this.OrchestrationInterfaceName);
			_ctdWFInterface.IsInterface = true;
			_ctdWFInterface.Attributes = MemberAttributes.Public;
			nsWFInterface.Types.Add(_ctdWFInterface);
			// add generic properties
			addPropertyToInterface(_ctdWFInterface, typeof(Guid), "InstanceId", true, true);
			addPropertyToInterface(_ctdWFInterface, typeof(bool), "IsDocumentFlowSimulation", true, true);
			addPropertyToInterface(_ctdWFInterface, typeof(bool), "IsSimulation", true, true);
			addPropertyToInterface(_ctdWFInterface, typeof(bool), "SimulateAllLogicalActivities", true, true);
			// add properties for rules and mapping
			addPropertyToInterface(_ctdWFInterface, "Rules", "Rules", true, false);
			addPropertyToInterface(_ctdWFInterface, "Mapping", "Mapping", true, false);
			#endregion

			TypeProvider typeProvider = (TypeProvider)getService<ITypeProvider>();
			_memberCreation.CreateProperty(this.FullClassName,
								   "LogicalActivitiesClass",
								   typeProvider.GetType(this.Namespace + ".LogicalActivities"),
								   null,
								   true,
								   false,
								   false,
								   null,
								   true);
			initLogicalActivitiesClassProperty(typeProvider);
		}
		#endregion

		#region generate members

		private void addPropertyToInterface(CodeTypeDeclaration type,
			string propType, string propName, bool hasGet, bool hasSet)
		{
			CodeMemberProperty prop = new CodeMemberProperty();
			prop.Name = propName;
			prop.Type = new CodeTypeReference(propType);
			prop.Attributes = 0;
			prop.HasGet = hasGet;
			prop.HasSet = hasSet;
			type.Members.Add(prop);
		}
		private void addPropertyToInterface(CodeTypeDeclaration type,
			Type propType, string propName, bool hasGet, bool hasSet)
		{
			CodeMemberProperty prop = new CodeMemberProperty();
			prop.Name = propName;
			prop.Type = new CodeTypeReference(propType);
			prop.Attributes = 0;
			prop.HasGet = hasGet;
			prop.HasSet = hasSet;
			type.Members.Add(prop);
		}

		private void addSimulationPropertiesToWFCodeBeside()
		{
			Debug.Assert(_memberCreation != null, "MemberCreationService not available.");

			_memberCreation.CreateProperty(this.FullClassName,
										   PropertyNames.IsSimulation,
										   typeof(bool),
										   null,
										   true,
										   false,
										   false,
										   null,
										   false);
			_memberCreation.CreateProperty(this.FullClassName,
											PropertyNames.IsDocumentFlowSimulation,
											typeof(bool),
											null,
											true,
											false,
											false,
											null,
											false);
			_memberCreation.CreateProperty(this.FullClassName,
										   PropertyNames.SimulateAllLogicalActivities,
										   typeof(bool),
										   null,
										   true,
										   false,
										   false,
										   null,
										   false);
		}
		#endregion

		#region type provider
		private void refreshTypeProvider(ref TypeProvider typeProvider, ref CodeCompileUnit codeUnit)
		{
			typeProvider.RemoveCodeCompileUnit(codeUnit);
			typeProvider.AddCodeCompileUnit(codeUnit);
			typeProvider.GetTypes();
			Debug.Assert(( typeProvider.TypeLoadErrors.Count == 0 ));
		}
		#endregion

		#region Members for Human Activities

		private void addHumanActivity(Repository.LogicalActivity logact, string url)
		{
			if ( logact == null ) throw new ArgumentNullException("logact");
			if ( logact.ExtendedProperties == null ||
				 logact.ExtendedProperties.HumanComponentProperties == null ) {
				return;
			}
			//if ( _dsHAProc == null )
			//initProcessDS();
			// read service properties
			Repository.HumanComponentProperties props =
				logact.ExtendedProperties.HumanComponentProperties;
			// get process row
			//DsProcessStructure.processRow rowProc =
			//    _dsHAProc.process.Rows[0] as DsProcessStructure.processRow;
			//DsProcessStructure.process_activityRow rowProcAct = null;
			//if ( this.Workflow.ExtendedProperties.LogicalActivityProcessActivities.ContainsKey(logact.ID) ) {
			//    rowProcAct = _dsHAProc.process_activity.FindByproc_act_id(
			//        this.Workflow.ExtendedProperties.LogicalActivityProcessActivities[logact.ID]);
			//}
			//if ( rowProcAct == null ) {
			//    // set process activity row
			//    rowProcAct = _dsHAProc.process_activity.Addprocess_activityRow(
			//        rowProc,
			//        logact.Name,
			//        logact.Description,
			//        "", true, 86400, 86400, 86400, 0f, "0", true, "Activity", false, false, 0, 0, false,
			//        false, false, url, props.AssemblyName, props.FormName, "", "");
			//} else {
			//    rowProcAct.proc_act_nm = logact.Name;
			//    rowProcAct.proc_act_desc = logact.Description;
			//    rowProcAct.activityservice_url = url;
			//    rowProcAct.assembly_name = props.AssemblyName;
			//    rowProcAct.assembly_form_name = props.FormName;
			//}

			// set process activity participants
			#region remove all previous participants
			//removeParticipantsOfActivity(_dsHAProc.process_activity_email_participant, rowProcAct.proc_act_id);
			//removeParticipantsOfActivity(_dsHAProc.process_activity_organization_participant, rowProcAct.proc_act_id);
			//removeParticipantsOfActivity(_dsHAProc.process_activity_organization_unit_participant, rowProcAct.proc_act_id);
			//removeParticipantsOfActivity(_dsHAProc.process_activity_property_participant, rowProcAct.proc_act_id);
			//removeParticipantsOfActivity(_dsHAProc.process_activity_role_participant, rowProcAct.proc_act_id);
			//removeParticipantsOfActivity(_dsHAProc.process_activity_user_participant, rowProcAct.proc_act_id);
			//removeParticipantsOfActivity(_dsHAProc.process_activity_activity_owner_participant, rowProcAct.proc_act_id);
			#endregion
			foreach ( HumanComponentParticipant part in props.Participants ) {
				#region add participant to dataset
				switch ( part.Type ) {
					case ParticipantType.EmailParticipant:
						//_dsHAProc.process_activity_email_participant.Addprocess_activity_email_participantRow(
						//    rowProcAct, (byte)part.PartTypeCD, part.Additional1);
						break;
					case ParticipantType.PropertyParticipant:
						//_dsHAProc.process_activity_property_participant.Addprocess_activity_property_participantRow(
						//    rowProcAct, (byte)part.PartTypeCD, part.Display);
						break;
					case ParticipantType.Organization:
						//_dsHAProc.process_activity_organization_participant.Addprocess_activity_organization_participantRow(
						//    rowProcAct, part.ID, (byte)part.PartTypeCD);
						break;
					case ParticipantType.OrganizationUnit:
						//_dsHAProc.process_activity_organization_unit_participant.Addprocess_activity_organization_unit_participantRow(
						//    rowProcAct, part.ID, (byte)part.PartTypeCD);
						break;
					case ParticipantType.ParticipantRule:
						break;
					case ParticipantType.PartnerRule:
						break;
					case ParticipantType.PartnerRole:
						break;
					case ParticipantType.Role:
						//_dsHAProc.process_activity_role_participant.Addprocess_activity_role_participantRow(
						//    rowProcAct, part.ID, (byte)part.PartTypeCD);
						break;
					case ParticipantType.User:
						//_dsHAProc.process_activity_user_participant.Addprocess_activity_user_participantRow(
						//    rowProcAct, part.ID, (byte)part.PartTypeCD);
						break;
					default:
						break;
				}
				#endregion
			}
			//this.Workflow.ExtendedProperties.LogicalActivityProcessActivities[logact.ID] =
			//    rowProcAct.proc_act_id;
			//saveHumanActivityProcess();
		}
		private void removeParticipantsOfActivity(DataTable dtPartType, int idProcAct)
		{
			DataRow[] rows = dtPartType.Select("proc_act_id = " + idProcAct);
			foreach ( DataRow row in rows ) {
				dtPartType.Rows.Remove(row);
			}
		}
		private void initProcessDS()
		{
			if ( this.Workflow.ExtendedProperties.ProcessID > 0 ) {
				//try {
				//    _dsHAProc = Global.ProcessData.GetCompleteProcess(
				//        this.Workflow.ExtendedProperties.ProcessID.ToString(), this.Workflow.OrganizationId.ToString());
				//} catch ( Exception ex ) {
				//    Debug.WriteLine("[InitProcessDS] " + ex.Message);
				//    this.Workflow.ExtendedProperties.ProcessID = -1;
				//    _dsHAProc = null;
				//}
			}
			//if ( _dsHAProc == null ) {
			//    _dsHAProc = new DsProcessStructure();
			//}
			//if ( _dsHAProc.process.Rows.Count == 0 ) {
			//    // add new process row
			//    DsProcessStructure.processRow rowProc =
			//        _dsHAProc.process.AddprocessRow(
			//            this.Workflow.Name,
			//            this.Workflow.OrganizationId,
			//            0,
			//            this.Workflow.Description,
			//            "", false, 0, 0, 0, false, "");
			//    // add process owner
			//    int userkey;
			//    if ( int.TryParse(Global.CurrentUser.UserKey, out userkey) ) {
			//        _dsHAProc.process_user_participant.Addprocess_user_participantRow(
			//            rowProc, userkey, (byte)5);
			//    }
			//}
		}
		private void saveHumanActivityProcess()
		{
			//if ( _dsHAProc == null || _dsHAProc.process.Rows.Count == 0 ||
			//     _dsHAProc.process_activity.Rows.Count == 0 ) {
			//    return;	// EXIT
			//}
			//            RepositoryService repSvc = (RepositoryService)this.GetService(typeof(RepositoryService));
			//            Debug.Assert(repSvc != null);
			//            Dictionary<int, int> deletedRows = new Dictionary<int, int>();
			//            foreach ( KeyValuePair<int,int> lp in this.Workflow.ExtendedProperties.LogicalActivityProcessActivities ) {
			//                int logactid = lp.Key;
			//                int procactid = lp.Value;
			//                bool deleted = false;
			//                try {
			//                    LogicalActivity la = repSvc.GetItem<LogicalActivity>(logactid);
			//                    if ( la == null || la.IsDeleted ) deleted = true;
			//                } catch ( RepositoryItemDeletedException ) {
			//                    deleted = true;
			//                }
			//                if ( deleted ) {
			//                    deletedRows.Add(logactid, procactid);
			//                }
			//            }
			//            foreach ( KeyValuePair<int,int> lp in deletedRows ) {
			//                this.Workflow.ExtendedProperties.LogicalActivityProcessActivities.Remove(lp.Key);
			//                DsProcessStructure.process_activityRow row = _dsHAProc.process_activity.FindByproc_act_id(lp.Value);
			//                if ( row != null ) row.Delete();
			//            }
			//SaveProcess:
			//            Hashtable htActIds;
			//            string procid = "";
			//            try {
			//                procid = Global.ProcessData.SaveProcess(
			//                    _dsHAProc,
			//                    this.Workflow.ExtendedProperties.ProcessID.ToString(),
			//                    this.Workflow.OrganizationId.ToString(),
			//                    Global.CurrentUser.UserKey,
			//                    ( this.Workflow.ExtendedProperties.ProcessID <= 0 ),
			//                    out htActIds);
			//            } catch ( Exception ex ) {
			//                Debug.WriteLine("[SaveHumanActivityProcess] " + ex.Message);
			//                if ( ex.Message.Contains("name you chose is already being used") ) {
			//                    DataTable dt = Global.ProcessData.GetProcesses(Global.CurrentUser.OrganizationID);
			//                    if ( dt != null && dt.Columns.Contains("proc_nm") ) {
			//                        foreach ( DataRow dr in dt.Rows ) {
			//                            if ( (string)dr["proc_nm"] == _dsHAProc.process[0].proc_nm ) {
			//                                Global.ProcessData.DeleteProcess(dr["proc_id"].ToString());
			//                                this.Workflow.ExtendedProperties.ProcessID = -1;
			//                                goto SaveProcess;
			//                            }
			//                        }
			//                    }
			//                    htActIds = null;
			//                    throw ex;
			//                } else {
			//                    htActIds = null;
			//                    throw ex;
			//                }
			//            }
			//            int idProc;
			//            if ( int.TryParse(procid, out idProc) ) this.Workflow.ExtendedProperties.ProcessID = idProc;

			//            foreach ( int oldid in htActIds.Keys ) {
			//                int[] keys = new int[this.Workflow.ExtendedProperties.LogicalActivityProcessActivities.Keys.Count];
			//                this.Workflow.ExtendedProperties.LogicalActivityProcessActivities.Keys.CopyTo(keys, 0);
			//                foreach ( int key in keys ) {
			//                    if ( this.Workflow.ExtendedProperties.LogicalActivityProcessActivities[key] == oldid ) {
			//                        this.Workflow.ExtendedProperties.LogicalActivityProcessActivities[key] =
			//                            (int)htActIds[oldid];
			//                    }
			//                }
			//            }
		}
		#endregion

		#region Mashup
		private void generateMashupForm()
		{
			// TODO: generate mashup form
		}
		#endregion

		#region Rules
		/// <summary>
		/// Adds the business rule to code.
		/// </summary>
		/// <param name="brule">The business rule.</param>
		private void AddRuleToCode(RepositoryBusinessRule brule)
		{
			Deployment deploy = new Deployment(_serviceContainer);
			deploy.AddRuleToCodeCompileUnit(brule, this.CodeRules, this.Workflow, this.RuleIDs, this.RuleConstantIDs);
		}
		/// <summary>
		/// Generates the rule constants code.
		/// </summary>
		/// <param name="repSvc">The rep SVC.</param>
		private void generateRuleConstantsCode(RepositoryService repSvc)
		{
			CodeConstructor ctorRules = null;
			if ( this.Workflow.IsConfigurable ) {
				ctorRules = new CodeConstructor();
				ctorRules.Attributes = MemberAttributes.Public;
				_ctdRules.Members.Add(ctorRules);
			}
			foreach ( int idRuleConst in this.RuleConstantIDs ) {
				RuleConstant rc = repSvc.GetItem(ItemType.RuleConstant, idRuleConst, true) as RuleConstant;
				if ( rc != null ) {
					CodeMemberField fieldConst = new CodeMemberField();
					fieldConst.Name = CodeGen.ConstPrefix + rc.Name;
					fieldConst.Type = new CodeTypeReference(Global.Data.GetDOTNETTypeofXSDDataType(rc.DataType));
					if ( this.Workflow.IsConfigurable ) {
						fieldConst.Attributes = MemberAttributes.Private;
						if ( ctorRules != null ) {
							// add intialization to ctor
							//try {
							//    this.CONST_HighBudgetScore = Convert.ChangeType(
							//        System.Configuration.ConfigurationManager.AppSettings["CONST_HighBudgetScore"],
							//        typeof(decimal));
							//} catch { }
							CodeTryCatchFinallyStatement codeTry = new CodeTryCatchFinallyStatement();
							codeTry.TryStatements.Add(
								new CodeAssignStatement(
									new CodeFieldReferenceExpression(null, fieldConst.Name),
									new CodeCastExpression(
										Global.Data.GetDOTNETTypeofXSDDataType(rc.DataType),
										new CodeMethodInvokeExpression(
											new CodeTypeReferenceExpression(typeof(Convert)),
											"ChangeType",
											new CodeArrayIndexerExpression(
												new CodePropertyReferenceExpression(
													new CodeTypeReferenceExpression(typeof(ConfigurationManager)),
													"AppSettings"),
												new CodePrimitiveExpression(fieldConst.Name)),
											new CodeTypeOfExpression(
												Global.Data.GetDOTNETTypeofXSDDataType(rc.DataType))))));
							codeTry.CatchClauses.Add(new CodeCatchClause());
							ctorRules.Statements.Add(codeTry);
							configuration.AppSettings.Settings.Add(fieldConst.Name, rc.Value);
						}
					} else {
						fieldConst.Attributes = MemberAttributes.Private | MemberAttributes.Const;
					}

					object val = rc.GetValueObject();
					if ( val != null ) {
						fieldConst.InitExpression = new CodePrimitiveExpression(val);
					} else {
						fieldConst.InitExpression = new CodeDefaultValueExpression(fieldConst.Type);
					}
					_ctdRules.Members.Add(fieldConst);
				}
			}
		}
		private RuleDefinitions getRuleDefinitions()
		{
			RuleDefinitions ruleDef = null;
			using ( TextReader tr = this.GetFileReader(".rules") )
			using ( XmlTextReader xtr = new XmlTextReader(tr) ) {
				if ( tr == null ) {
					ruleDef = new RuleDefinitions();
				} else {
					WorkflowMarkupSerializer serializer = new WorkflowMarkupSerializer();
					ruleDef = serializer.Deserialize(xtr) as RuleDefinitions;
				}
			}
			return ruleDef;
		}
		private void setRuleDefinitions(RuleDefinitions ruleDef)
		{
			using ( TextWriter tw = this.GetFileWriter(".rules") )
			using ( XmlTextWriter xtw = new XmlTextWriter(tw) ) {
				WorkflowMarkupSerializer serializer = new WorkflowMarkupSerializer();
				serializer.Serialize(xtw, ruleDef);
			}
		}

		private bool existsRuleParameterResolve(KeyValuePair<string, string> item)
		{
			bool paramexists = this.Workflow.ExtendedProperties.WorkflowVariables.Exists(
				delegate(Repository.Workflow.RuleParameterResolve rpr)
				{
					return ( rpr.ParameterName == item.Key );
				});
			return paramexists;
		}
		private static bool existsNounInResolveList(BindingListEx<Repository.Workflow.RuleParameterResolve> lst, int id)
		{
			return lst.Exists(delegate(Repository.Workflow.RuleParameterResolve rpr)
			{
				return ( rpr.ParameterID == id );
			});
		}
		private static Repository.Workflow.RuleParameterResolve getRPRByName(
			BindingListEx<Repository.Workflow.RuleParameterResolve> lst, string name)
		{
			return lst.Find(delegate(Repository.Workflow.RuleParameterResolve rpr)
			{
				return ( rpr.ParameterName == name );
			});
		}
		/// <summary>
		/// Retrieves an object that <see cref="T:System.Workflow.ComponentModel.Design.WorkflowDesignerLoader"/> uses to read from the specified file.
		/// </summary>
		/// <param name="filePath">A string that contains a path to the file to read from.</param>
		/// <returns>
		/// A <see cref="T:System.IO.TextReader"/> to read the specified file.
		/// </returns>
		public TextReader GetFileReader(string filePath)
		{
			if ( this.tempRulesStream != null )
				return new StringReader(this.tempRulesStream.ToString());
			else
				return null;
		}

		/// <summary>
		/// Gets an object that the <see cref="T:System.Workflow.ComponentModel.Design.WorkflowDesignerLoader"/> uses to write to the specified file.
		/// </summary>
		/// <param name="filePath">A string that contains the path to the file to write to.</param>
		/// <returns>
		/// A <see cref="T:System.IO.TextWriter"/> to write to the file.
		/// </returns>
		public TextWriter GetFileWriter(string filePath)
		{
			this.tempRulesStream = new StringBuilder();
			return new StringWriter(this.tempRulesStream);
		}

		#endregion

		#region Code Beside
		private void addProcessVariablesToCodeBeside()
		{
			TypeProvider typeProvider = (TypeProvider)this.GetService(typeof(ITypeProvider));
			MemberCreationService memberCreate = (MemberCreationService)this.GetService(typeof(IMemberCreationService));
			Debug.Assert(typeProvider != null);
			Debug.Assert(memberCreate != null);

			foreach ( Repository.WorkflowField var in this.Workflow.Interface.Fields ) {
				Type type = Global.Data.GetDOTNETTypeofXSDDataType(var.DataType);
				if ( type == null ) {
					type = typeProvider.GetType(var.DataType);
				}
				memberCreate.CreateProperty(this.Workflow.ExtendedProperties.FullName,
											var.Name,
											type,
											null, true, false, false, null, false);
			}
		}
		private void addMethodCodeSnippetsToCodeBeside(Deployment deployment)
		{
			foreach ( Repository.Workflow.MethodCodeSnippet snip in
						this.Workflow.ExtendedProperties.MethodCodeSnippets ) {
				CodeMemberMethod meth =
					deployment.getMethodFromCode(ccuBeside, this.FullClassName, snip.MethodName);
				if ( meth == null ) {
					meth = new CodeMemberMethod();
					meth.Name = snip.MethodName;
					meth.ReturnType = new CodeTypeReference(snip.ReturnType);
					foreach ( Repository.Workflow.MethodParameter par in snip.MethodParameters ) {
						meth.Parameters.Add(
							new CodeParameterDeclarationExpression(par.Type, par.Name));
					}
					string code = snip.Code;
					if ( !string.IsNullOrEmpty(code) && !code.Contains(Environment.NewLine) ) {
						code = code.Replace("\n", Environment.NewLine);
					}
					meth.Statements.Add(
						new CodeSnippetStatement(code));
					ccuBeside.Namespaces[0].Types[0].Members.Add(meth);
				}
			}
		}
		private void addPropertyForBObjectToCodeBeside(TypeProvider typeProvider,
			Repository.BusinessObject bobj, CodeTypeReference typeRefBObj)
		{
			_memberCreation.CreateProperty(this.FullClassName,
										   bobj.Name + Deployment.cBObjPropSuffix,
										   typeProvider.GetType(typeRefBObj.BaseType),
										   null,
										   true,
										   false,
										   false,
										   null,
										   false);
		}
		#endregion

		#region Local Service Interface and Implementation

		private void generateLocalService()
		{
			string startOpName = null;
			CodeTypeReference typeRefInput = null;
			CodeTypeReference typeRefOutput = null;
			CodeNamespace nsLocalSvc = ccuLocalService.Namespaces[0];

			#region get start operation informations
			TypeProvider typeProvider = (TypeProvider)GetService(typeof(ITypeProvider));

			Repository.Operation op = null;
			BindingListEx<Repository.Operation> ops =
				Global.Data.GetWorkflowOperation(this.Workflow.ID);
			if ( ops.Count <= 0 ) {
				if ( this.Workflow.Type != OpenComposite.EII.Repository.WorkflowType.Business_Process )
					throw new Exception("No orchestration start operation exists.");
			} else {
				op = ops[0];
			}
			if ( op != null ) {
				startOpName = op.Name;
				getGeneratedIOTypesOfOperation(typeProvider, op, out typeRefOutput, out typeRefInput);
			} else if ( !string.IsNullOrEmpty(this.Workflow.StartName) ) {
				startOpName = this.Workflow.StartName;
				getGeneratedIOTypesOfWorkflow(typeProvider, this.Workflow, out typeRefOutput, out typeRefInput);
			}
			if ( string.IsNullOrEmpty(startOpName) ) {
				Debug.WriteLine("No start operation available.");
				return;
			}
			#endregion

			generateLocalSvcInterface(nsLocalSvc, typeRefInput, typeRefOutput, startOpName);
			generateLocalSvcClass(nsLocalSvc, typeRefInput, typeRefOutput, startOpName);

			refreshTypeProvider(ref typeProvider, ref ccuLocalService);
		}

		private void generateLocalSvcInterface(CodeNamespace nsLocalSvc,
			CodeTypeReference typeRefInput, CodeTypeReference typeRefOutput, string startOpName)
		{
			#region add ExternalDataEventArgs class for start event
			CodeTypeDeclaration ctdEventArgs = new CodeTypeDeclaration(startOpName + Deployment.cEventArgs);
			ctdEventArgs.Attributes = MemberAttributes.Public | MemberAttributes.Final;
			//	add SerializableAttribute
			ctdEventArgs.CustomAttributes.Add(
				new CodeAttributeDeclaration(new CodeTypeReference(typeof(SerializableAttribute))));
			//	add Base Class
			ctdEventArgs.BaseTypes.Add(typeof(ExternalDataEventArgs));
			//	add Constuctor
			CodeConstructor ctorEventArgs = new CodeConstructor();
			ctorEventArgs.Attributes = MemberAttributes.Final | MemberAttributes.Public;
			ctorEventArgs.Parameters.Add(	// XEventArgs(Guid instanceId, ...)
				new CodeParameterDeclarationExpression(typeof(Guid), "instanceId"));
			//			: base(instanceId);
			ctorEventArgs.BaseConstructorArgs.Add(new CodeArgumentReferenceExpression("instanceId"));
			if ( typeRefInput != null ) {
				ctorEventArgs.Parameters.Add(	// XEventArgs(..., InputType input)
					new CodeParameterDeclarationExpression(typeRefInput, "input"));
				ctorEventArgs.Statements.Add(	// _input = input;
					new CodeAssignStatement(
						new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), "_input"),
						new CodeArgumentReferenceExpression("input")));
			}
			ctdEventArgs.Members.Add(ctorEventArgs);
			if ( typeRefInput != null ) {
				//	add private input data field
				ctdEventArgs.Members.Add(
					new CodeMemberField(typeRefInput, "_input"));
				//	add public input data property (get)
				CodeMemberProperty propInput = new CodeMemberProperty();
				propInput.Name = "Input";
				propInput.Attributes = MemberAttributes.Public | MemberAttributes.Final;
				propInput.Type = typeRefInput;
				propInput.HasGet = true;
				propInput.HasSet = false;
				propInput.GetStatements.Add(
					new CodeMethodReturnStatement(
						new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), "_input")));

				ctdEventArgs.Members.Add(propInput);
			}
			// add EventArgs class to namespace
			nsLocalSvc.Types.Add(ctdEventArgs);
			#endregion

			#region add start event handler delegate
			// public delegate void XEventHandler(object sender, XEventArgs e);
			CodeTypeDelegate delegateEvent = new CodeTypeDelegate();
			delegateEvent.Name = startOpName + Deployment.cEventHandler;
			delegateEvent.Attributes = MemberAttributes.Public | MemberAttributes.Final;
			delegateEvent.Parameters.Add(
				new CodeParameterDeclarationExpression(typeof(object), "sender"));
			delegateEvent.Parameters.Add(
				new CodeParameterDeclarationExpression(ctdEventArgs.Name, "e"));
			// add delegate to namespace
			nsLocalSvc.Types.Add(delegateEvent);
			#endregion

			if ( typeRefOutput != null ) {
				#region add ReplyEventArgs class for reply method
				CodeTypeDeclaration ctdEAReply = new CodeTypeDeclaration();
				ctdEAReply.Name = startOpName + Deployment.c_Reply + Deployment.cEventArgs;
				//	add SerializableAttribute
				ctdEAReply.CustomAttributes.Add(
					new CodeAttributeDeclaration(new CodeTypeReference(typeof(SerializableAttribute))));
				//	add Base Class
				ctdEAReply.BaseTypes.Add(typeof(EventArgs));
				//	add Constuctor
				CodeConstructor ctorEAReply = new CodeConstructor();
				ctorEAReply.Attributes = MemberAttributes.Final | MemberAttributes.Public;
				ctorEAReply.Parameters.Add(	// X_ReplyEventArgs(Guid instanceId, ...)
					new CodeParameterDeclarationExpression(typeof(Guid), "instanceId"));
				ctorEAReply.Parameters.Add(	// X_ReplyEventArgs(..., OutputType output)
					new CodeParameterDeclarationExpression(typeRefOutput, "output"));
				ctorEAReply.Statements.Add(	// _instanceId = instanceId
					new CodeAssignStatement(
						new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), "_instanceId"),
						new CodeArgumentReferenceExpression("instanceId")));
				ctorEAReply.Statements.Add(	// _output = output;
					new CodeAssignStatement(
						new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), "_output"),
						new CodeArgumentReferenceExpression("output")));
				ctdEAReply.Members.Add(ctorEAReply);

				//	add private data fields
				ctdEAReply.Members.Add(
					new CodeMemberField(typeof(Guid), "_instanceId"));
				ctdEAReply.Members.Add(
					new CodeMemberField(typeRefOutput, "_output"));
				//	add public data properties (get)
				CodeMemberProperty propInstanceID = new CodeMemberProperty();
				propInstanceID.Name = "InstanceId";
				propInstanceID.Attributes = MemberAttributes.Public | MemberAttributes.Final;
				propInstanceID.Type = new CodeTypeReference(typeof(Guid));
				propInstanceID.HasGet = true;
				propInstanceID.HasSet = false;
				propInstanceID.GetStatements.Add(
					new CodeMethodReturnStatement(
						new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), "_instanceId")));
				CodeMemberProperty propOutput = new CodeMemberProperty();
				propOutput.Name = "Output";
				propOutput.Attributes = MemberAttributes.Public | MemberAttributes.Final;
				propOutput.Type = typeRefOutput;
				propOutput.HasGet = true;
				propOutput.HasSet = false;
				propOutput.GetStatements.Add(
					new CodeMethodReturnStatement(
						new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), "_output")));

				ctdEAReply.Members.Add(propInstanceID);
				ctdEAReply.Members.Add(propOutput);
				// add ReplyEventArgs class to namespace
				nsLocalSvc.Types.Add(ctdEAReply);
				#endregion

				#region add reply event handler delegate
				// public delegate void X_ReplyEventHandler(object sender, X_ReplyEventArgs e);
				CodeTypeDelegate delegateReplyEvent = new CodeTypeDelegate();
				delegateReplyEvent.Name = startOpName + Deployment.c_Reply + Deployment.cEventHandler;
				delegateReplyEvent.Attributes = MemberAttributes.Public | MemberAttributes.Final;
				delegateReplyEvent.Parameters.Add(
					new CodeParameterDeclarationExpression(typeof(object), "sender"));
				delegateReplyEvent.Parameters.Add(
					new CodeParameterDeclarationExpression(ctdEAReply.Name, "e"));
				// add delegate to namespace
				nsLocalSvc.Types.Add(delegateReplyEvent);
				#endregion

				#region add reply method to interface
				// void Start_Reply(OutputType output);
				CodeMemberMethod methodReply = new CodeMemberMethod();
				methodReply.Name = startOpName + Deployment.c_Reply;
				methodReply.Attributes = MemberAttributes.Public;
				methodReply.Parameters.Add(
					new CodeParameterDeclarationExpression(typeof(Guid), "workflowInstanceId"));
				methodReply.Parameters.Add(
					new CodeParameterDeclarationExpression(typeRefOutput, "output"));
				// add output method to interface
				_ctdLocalInterface.Members.Add(methodReply);
				#endregion
			}

			#region add start event to interface
			// event XEventHandler
			CodeMemberEvent eventStart = new CodeMemberEvent();
			eventStart.Name = startOpName;
			eventStart.Type = new CodeTypeReference(delegateEvent.Name);
			eventStart.Attributes = (MemberAttributes)0;
			// add event to local interface
			_ctdLocalInterface.Members.Add(eventStart);
			#endregion

		}

		private void generateLocalSvcClass(CodeNamespace nsLocalSvc,
			CodeTypeReference typeRefInput, CodeTypeReference typeRefOutput, string startOpName)
		{
			#region add constructor
			CodeConstructor ctorLocalSvc = new CodeConstructor();
			ctorLocalSvc.Attributes = MemberAttributes.Public | MemberAttributes.Final;
			ctorLocalSvc.Parameters.Add(
				new CodeParameterDeclarationExpression(typeof(WorkflowRuntime), "workflowRuntime"));
			// add to local service class
			_ctdLocalService.Members.Add(ctorLocalSvc);
			#endregion

			#region add events
			// create start event
			CodeMemberEvent eventStart = new CodeMemberEvent();
			eventStart.Name = startOpName;
			eventStart.Attributes = MemberAttributes.Final | MemberAttributes.Public;
			eventStart.Type = new CodeTypeReference(startOpName + Deployment.cEventHandler);
			// add event to local service class
			_ctdLocalService.Members.Add(eventStart);

			if ( typeRefOutput != null ) {
				// create reply event
				CodeMemberEvent eventReply = new CodeMemberEvent();
				eventReply.Name = startOpName + Deployment.c_Reply + "Event";
				eventReply.Attributes = MemberAttributes.Final | MemberAttributes.Public;
				eventReply.Type = new CodeTypeReference(startOpName + Deployment.c_Reply + Deployment.cEventHandler);
				// add event to local service class
				_ctdLocalService.Members.Add(eventReply);
			}
			#endregion

			#region implement raise start event method
			CodeMemberMethod methodRaiseStart = new CodeMemberMethod();
			methodRaiseStart.Attributes = MemberAttributes.Public | MemberAttributes.Final;
			methodRaiseStart.Name = Deployment.cRaise + startOpName + Deployment.cEvent;
			methodRaiseStart.Parameters.Add(
				new CodeParameterDeclarationExpression(typeof(Guid), "workflowInstanceId"));
			if ( typeRefInput != null ) {
				methodRaiseStart.Parameters.Add(
					new CodeParameterDeclarationExpression(typeRefInput, "input"));
			}
			// XEventArgs e = new XEventArgs(workflowInstanceId[, input]);
			CodeObjectCreateExpression createE = new CodeObjectCreateExpression();
			createE.CreateType = new CodeTypeReference(startOpName + Deployment.cEventArgs);
			createE.Parameters.Add(new CodeArgumentReferenceExpression("workflowInstanceId"));
			if ( typeRefInput != null ) {
				createE.Parameters.Add(new CodeArgumentReferenceExpression("input"));
			}
			methodRaiseStart.Statements.Add(
				new CodeVariableDeclarationStatement(
					startOpName + Deployment.cEventArgs,
					"e",
					createE));
			// XEventHandler tmp = this.StartOp;
			methodRaiseStart.Statements.Add(
				new CodeVariableDeclarationStatement(
					startOpName + Deployment.cEventHandler,
					"tmp",
					new CodeEventReferenceExpression(new CodeThisReferenceExpression(), startOpName)));
			// if ( tmp != null )
			methodRaiseStart.Statements.Add(
				new CodeConditionStatement(
					new CodeBinaryOperatorExpression(
						new CodeVariableReferenceExpression("tmp"),
						CodeBinaryOperatorType.IdentityInequality,
						new CodePrimitiveExpression(null)),
					new CodeStatement[] {
						new CodeExpressionStatement(
						new CodeDelegateInvokeExpression( // tmp(this, e);
							new CodeVariableReferenceExpression("tmp"),
							new CodePrimitiveExpression(null),
							new CodeVariableReferenceExpression("e")))
					}));
			_ctdLocalService.Members.Add(methodRaiseStart);
			#endregion

			if ( typeRefOutput != null ) {
				#region implement output method
				// public void Start_Reply(Guid workflowInstanceId, OutputType output) {
				CodeMemberMethod methReply = new CodeMemberMethod();
				methReply.Name = startOpName + Deployment.c_Reply;
				methReply.Attributes = MemberAttributes.Final | MemberAttributes.Public;
				methReply.Parameters.Add(
					new CodeParameterDeclarationExpression(typeof(Guid), "workflowInstanceId"));
				methReply.Parameters.Add(
					new CodeParameterDeclarationExpression(typeRefOutput, "output"));
				//		X_ReplyEventArgs e = new X_ReplyEventArgs(workflowInstanceId, output);
				methReply.Statements.Add(
					new CodeVariableDeclarationStatement(
						startOpName + Deployment.c_Reply + Deployment.cEventArgs,
						"e",
						new CodeObjectCreateExpression(
							startOpName + Deployment.c_Reply + Deployment.cEventArgs,
							new CodeVariableReferenceExpression("workflowInstanceId"),
							new CodeVariableReferenceExpression("output"))));
				//		XReplyEventHandler tmp = this.XReplyEvent;
				methReply.Statements.Add(
					new CodeVariableDeclarationStatement(
						startOpName + Deployment.c_Reply + Deployment.cEventHandler,
						"tmp",
						new CodeEventReferenceExpression(
							new CodeThisReferenceExpression(),
							startOpName + Deployment.c_Reply + Deployment.cEvent)));
				//		if ( tmp != null )
				methReply.Statements.Add(
					new CodeConditionStatement(
						new CodeBinaryOperatorExpression(
							new CodeVariableReferenceExpression("tmp"),
							CodeBinaryOperatorType.IdentityInequality,
							new CodePrimitiveExpression(null)),
					//			tmp(this, e);
					new CodeExpressionStatement(
					new CodeDelegateInvokeExpression(
						new CodeVariableReferenceExpression("tmp"),
						new CodePrimitiveExpression(null),
						new CodeVariableReferenceExpression("e")))));
				// }
				_ctdLocalService.Members.Add(methReply);
				#endregion
			}
		}

		#endregion

		#region Generate External Data Exchange Code

		private void generateProxyForMashup(Deployment deployment)
		{
			#region Initialize
			TypeProvider typeProvider = GetService(typeof(ITypeProvider)) as TypeProvider;
			Debug.Assert(typeProvider != null);

			CodeNamespace nsEmpty = new CodeNamespace();
			nsEmpty.Imports.Add(new CodeNamespaceImport("System.Workflow.Activities"));
			ccuLocalService.Namespaces.Add(nsEmpty);
			#endregion

			#region Generate Proxy Class

			#region create constructor
			CodeConstructor ctorProxy = new CodeConstructor();
			ctorProxy.Attributes = MemberAttributes.Public;
			ctorProxy.StartDirectives.Add(new CodeRegionDirective(CodeRegionMode.Start, "Initialization"));
			ctorProxy.EndDirectives.Add(new CodeRegionDirective(CodeRegionMode.End, "Initialization"));
			// ExternalDataExchangeService extdatasvc = new ExternalDataExchangeService()
			ctorProxy.Statements.Add(
				new CodeVariableDeclarationStatement(
					typeof(ExternalDataExchangeService),
					Deployment.cExtDataSvc,
					new CodeObjectCreateExpression(typeof(ExternalDataExchangeService))));
			// _wfRuntime = new WorkflowRuntime();
			ctorProxy.Statements.Add(
				new CodeAssignStatement(
					new CodeFieldReferenceExpression(
						new CodeThisReferenceExpression(), Deployment.c_wfRuntime),
					new CodeObjectCreateExpression(typeof(WorkflowRuntime))));
			// _wfRuntime.AddService(extdatasvc);
			ctorProxy.Statements.Add(
				new CodeMethodInvokeExpression(
					new CodeFieldReferenceExpression(
						new CodeThisReferenceExpression(), Deployment.c_wfRuntime),
					Deployment.cAddService,
					new CodeVariableReferenceExpression(Deployment.cExtDataSvc)));
			// _wfRuntime.StartRuntime();
			ctorProxy.Statements.Add(
				new CodeMethodInvokeExpression(
					new CodeFieldReferenceExpression(
						new CodeThisReferenceExpression(), Deployment.c_wfRuntime),
					Deployment.cStartRuntime));
			// extdatasvc.AddService(this);
			ctorProxy.Statements.Add(
				new CodeMethodInvokeExpression(
					new CodeVariableReferenceExpression(Deployment.cExtDataSvc),
					Deployment.cAddService,
					new CodeThisReferenceExpression()));
			// _wfInstance = null;
			ctorProxy.Statements.Add(
				new CodeAssignStatement(
					new CodeFieldReferenceExpression(
						new CodeThisReferenceExpression(), Deployment.c_wfInstance),
					new CodePrimitiveExpression(null)));
			_ctdLocalService.Members.Add(ctorProxy);
			#endregion

			#region add private fields
			_ctdLocalService.Members.Add(
				new CodeMemberField(typeof(WorkflowRuntime), Deployment.c_wfRuntime));
			_ctdLocalService.Members.Add(
				new CodeMemberField(typeof(WorkflowInstance), Deployment.c_wfInstance));
			#endregion

			#region add properties
			CodeMemberProperty propWFRTM = new CodeMemberProperty();
			propWFRTM.Name = Deployment.cRuntime;
			propWFRTM.Attributes = MemberAttributes.Public | MemberAttributes.Final;
			propWFRTM.Type = new CodeTypeReference(typeof(WorkflowRuntime));
			propWFRTM.HasGet = true;
			propWFRTM.HasSet = false;
			propWFRTM.GetStatements.Add(
				new CodeMethodReturnStatement(
					new CodeFieldReferenceExpression(
						new CodeThisReferenceExpression(), Deployment.c_wfRuntime)));
			_ctdLocalService.Members.Add(propWFRTM);
			#endregion

			#region add IDisposable
			// add IDisposable to class
			_ctdLocalService.BaseTypes.Add(typeof(IDisposable));

			// implement Dispose method
			CodeMemberMethod methDispose = new CodeMemberMethod();
			methDispose.Attributes = MemberAttributes.Public | MemberAttributes.Final;
			methDispose.Name = Deployment.cDispose;
			methDispose.StartDirectives.Add(new CodeRegionDirective(CodeRegionMode.Start, "IDisposable Members"));
			methDispose.EndDirectives.Add(new CodeRegionDirective(CodeRegionMode.End, "IDisposable Members"));
			methDispose.Statements.Add(
				new CodeMethodInvokeExpression(
					new CodeFieldReferenceExpression(
						new CodeThisReferenceExpression(), Deployment.c_wfRuntime),
					Deployment.cStopRuntime));
			methDispose.Statements.Add(
				new CodeMethodInvokeExpression(
					new CodeFieldReferenceExpression(
						new CodeThisReferenceExpression(), Deployment.c_wfRuntime),
					Deployment.cDispose));
			methDispose.Statements.Add(
				new CodeAssignStatement(
					new CodeFieldReferenceExpression(
						new CodeThisReferenceExpression(), Deployment.c_wfRuntime),
					new CodePrimitiveExpression(null)));
			methDispose.Statements.Add(
				new CodeAssignStatement(
					new CodeFieldReferenceExpression(
						new CodeThisReferenceExpression(), Deployment.c_wfInstance),
					new CodePrimitiveExpression(null)));
			_ctdLocalService.Members.Add(methDispose);
			#endregion

			#endregion

			#region Add Events
			foreach ( Repository.WorkflowEvent we in this.Workflow.Interface.Events ) {
				// create ExternalDataEventArgs class for event business object
				CodeTypeReference typeRefBObj;
				string classEventArgsName = createExternalDataEventArgsClass(deployment, typeProvider, we, out typeRefBObj);
				string delegateName = we.Name + Deployment.cEventHandler;

				// create delegate for ExternalDataEventArgs
				createEventDelegate(delegateName, classEventArgsName);

				// add event to interface (public interface I<WFNAME>Local)
				// event XEventHandler NAME;
				CodeMemberEvent interfaceEvent = new CodeMemberEvent();
				interfaceEvent.Name = we.Name;
				interfaceEvent.Type = new CodeTypeReference(delegateName);
				interfaceEvent.Attributes = (MemberAttributes)0;
				// add event to local interface
				_ctdLocalInterface.Members.Add(interfaceEvent);

				// add event to interface implementation (public class <WFNAME>Local : I<WFNAME>Local)
				CodeMemberEvent classEvent = new CodeMemberEvent();
				classEvent.Name = we.Name;
				classEvent.Attributes = MemberAttributes.Final | MemberAttributes.Public;
				classEvent.Type = new CodeTypeReference(delegateName);
				// add event to local service class
				_ctdLocalService.Members.Add(classEvent);

				// add "RaiseEvent" method to interface implementation
				addRaiseEventToInterfaceImplementation(we, typeRefBObj, classEventArgsName, delegateName);

				// add properties to code beside

				// create workflowInstanceId Property
				_memberCreation.CreateProperty(this.FullClassName,
											   PropertyNames.WorkflowInstanceId,
											   typeof(Guid),
											   null,
											   true,
											   false,
											   false,
											   null,
											   false);

				// add EventArgs property and assign to input property
				if ( typeRefBObj != null ) {
					Type t = typeProvider.GetType(this.Namespace + "." + classEventArgsName);
					_memberCreation.CreatePropertyForWCFInputEventArgs(this.FullClassName,
						classEventArgsName,
						t,
						we.BusinessObjectName, PropertyNames.WorkflowInstanceId);
				}
				// add event method to wcf service contract
				CodeMemberMethod meth = new CodeMemberMethod();
				meth.Attributes = 0;
				meth.CustomAttributes.Add(
					new CodeAttributeDeclaration(
						new CodeTypeReference(typeof(OperationContractAttribute)),
						new CodeAttributeArgument("IsOneWay", new CodePrimitiveExpression(true))));
				meth.Name = we.Name;
				if ( typeRefBObj != null ) {
					meth.Parameters.Add(
						new CodeParameterDeclarationExpression(typeRefBObj, "input"));
				}
				_ctdInterface.Members.Add(meth);
			}
			#endregion

			#region Add Methods
			foreach ( Repository.WorkflowMethod wm in this.Workflow.Interface.Methods ) {
				CodeTypeReference typeRefInput, typeRefOutput;
				// create EventArgs class for interface method implementation
				string classEventArgsName = createEventArgsClass(deployment, typeProvider, wm,
					out typeRefInput, out typeRefOutput);
				string delegateName = wm.Name + Deployment.cEventHandler;

				// create delegate for EventArgs
				if ( string.IsNullOrEmpty(classEventArgsName) ) {
					classEventArgsName = wm.Name + Deployment.cEventArgs;
				} else {
					createEventDelegate(delegateName, classEventArgsName);
				}

				// add method to interface
				CodeMemberMethod interfaceMethod = new CodeMemberMethod();
				interfaceMethod.Name = wm.Name;
				interfaceMethod.Attributes = MemberAttributes.Public;
				interfaceMethod.Parameters.Add(
					new CodeParameterDeclarationExpression(typeof(Guid), "workflowInstanceId"));
				if ( typeRefInput != null ) {
					// add method input parameter
					interfaceMethod.Parameters.Add(
						new CodeParameterDeclarationExpression(typeRefInput, Deployment.cMethodInput));
				}
				if ( typeRefOutput != null ) {
					// set return value
					interfaceMethod.ReturnType = typeRefOutput;
				}
				// add output method to interface
				_ctdLocalInterface.Members.Add(interfaceMethod);

				// add event to interface implementation class
				CodeMemberEvent classEvent = new CodeMemberEvent();
				classEvent.Name = wm.Name + Deployment.cEvent;
				classEvent.Attributes = MemberAttributes.Final | MemberAttributes.Public;
				classEvent.Type = new CodeTypeReference(delegateName);
				// add event to local service class
				_ctdLocalService.Members.Add(classEvent);

				// add method implementation to invoke the created event
				addMethodToInterfaceImplementation(wm, typeRefInput, typeRefOutput,
												   classEventArgsName, delegateName);

				// add method to wcf service callback contract
				CodeMemberMethod meth = new CodeMemberMethod();
				meth.Attributes = 0;
				if ( typeRefOutput != null ) {
					meth.CustomAttributes.Add(
						new CodeAttributeDeclaration(
							new CodeTypeReference(typeof(OperationContractAttribute))));
					meth.ReturnType = typeRefOutput;
				} else {
					meth.CustomAttributes.Add(
						new CodeAttributeDeclaration(
							new CodeTypeReference(typeof(OperationContractAttribute)),
							new CodeAttributeArgument("IsOneWay", new CodePrimitiveExpression(true))));
				}
				meth.Name = wm.Name;
				if ( typeRefInput != null ) {
					meth.Parameters.Add(
						new CodeParameterDeclarationExpression(typeRefInput, Deployment.cMethodOutput));
				}
				_ctdInterfaceCallback.Members.Add(meth);
			}
			#endregion
		}
		private void generateProxyForWCFService(Deployment deployment)
		{
			#region Initialize
			TypeProvider typeProvider = GetService(typeof(ITypeProvider)) as TypeProvider;
			Debug.Assert(typeProvider != null);

			CodeNamespace nsEmpty = new CodeNamespace();
			nsEmpty.Imports.Add(new CodeNamespaceImport("System"));
			nsEmpty.Imports.Add(new CodeNamespaceImport("System.Collections.Generic"));
			nsEmpty.Imports.Add(new CodeNamespaceImport("System.Text"));
			nsEmpty.Imports.Add(new CodeNamespaceImport("System.Workflow.Activities"));
			nsEmpty.Imports.Add(new CodeNamespaceImport("System.Workflow.Runtime"));
			nsEmpty.Imports.Add(new CodeNamespaceImport(this.Namespace));
			nsEmpty.Imports.Add(new CodeNamespaceImport(this.NamespaceData));
			ccuLocalService.Namespaces.Add(nsEmpty);

			#region create Host Service Constructor
			CodeConstructor ctorHost = new CodeConstructor();
			ctorHost.Statements.Add(
				new CodeAssignStatement(
					new CodeFieldReferenceExpression(
						new CodeThisReferenceExpression(), "_callback"),
					new CodePrimitiveExpression(null)));
			ctorHost.Statements.Add(
				new CodeAttachEventStatement(
					new CodePropertyReferenceExpression(
						new CodePropertyReferenceExpression(
							new CodeTypeReferenceExpression(_ctdLocalService.Name),
							"Instance"),
						"Runtime"),
					"WorkflowCompleted",
					new CodeObjectCreateExpression(
						new CodeTypeReference(
							"EventHandler",
							new CodeTypeReference(typeof(WorkflowCompletedEventArgs))),
						new CodeMethodReferenceExpression(
							new CodeThisReferenceExpression(), "runtime_WorkflowCompleted"))));
			ctorHost.Statements.Add(
				new CodeAttachEventStatement(
					new CodePropertyReferenceExpression(
						new CodePropertyReferenceExpression(
							new CodeTypeReferenceExpression(_ctdLocalService.Name),
							"Instance"),
						"Runtime"),
					"WorkflowAborted",
					new CodeObjectCreateExpression(
						new CodeTypeReference(
							"EventHandler",
							new CodeTypeReference(typeof(WorkflowEventArgs))),
						new CodeMethodReferenceExpression(
							new CodeThisReferenceExpression(), "runtime_WorkflowAborted"))));
			ctorHost.Statements.Add(
				new CodeAttachEventStatement(
					new CodePropertyReferenceExpression(
						new CodePropertyReferenceExpression(
							new CodeTypeReferenceExpression(_ctdLocalService.Name),
							"Instance"),
						"Runtime"),
					"WorkflowTerminated",
					new CodeObjectCreateExpression(
						new CodeTypeReference(
							"EventHandler",
							new CodeTypeReference(typeof(WorkflowTerminatedEventArgs))),
						new CodeMethodReferenceExpression(
							new CodeThisReferenceExpression(), "runtime_WorkflowTerminated"))));
			_ctdHostService.Members.Add(ctorHost);
			#endregion

			#region create Host Service proxy workflow runtime event handlers
			CodeMemberMethod mCleanUp = new CodeMemberMethod();
			mCleanUp.Attributes = MemberAttributes.Private | MemberAttributes.Final;
			mCleanUp.Name = "cleanup";
			mCleanUp.Parameters.Add(
				new CodeParameterDeclarationExpression(typeof(Guid), "instanceId"));
			CodeConditionStatement condCleanUp = new CodeConditionStatement();
			mCleanUp.Statements.Add(condCleanUp);
			condCleanUp.Condition =
				new CodeBinaryOperatorExpression(
					new CodeFieldReferenceExpression(
						new CodeThisReferenceExpression(), "_instanceId"),
					CodeBinaryOperatorType.ValueEquality,
					new CodeArgumentReferenceExpression("instanceId"));
			#region Remove Workflow Events
			condCleanUp.TrueStatements.Add(
				new CodeRemoveEventStatement(
					new CodePropertyReferenceExpression(
						new CodePropertyReferenceExpression(
							new CodeTypeReferenceExpression(_ctdLocalService.Name),
							"Instance"),
						"Runtime"),
					"WorkflowCompleted",
					new CodeObjectCreateExpression(
						new CodeTypeReference(
							"EventHandler",
							new CodeTypeReference(typeof(WorkflowCompletedEventArgs))),
						new CodeMethodReferenceExpression(
							new CodeThisReferenceExpression(), "runtime_WorkflowCompleted"))));
			condCleanUp.TrueStatements.Add(
				new CodeRemoveEventStatement(
					new CodePropertyReferenceExpression(
						new CodePropertyReferenceExpression(
							new CodeTypeReferenceExpression(_ctdLocalService.Name),
							"Instance"),
						"Runtime"),
					"WorkflowAborted",
					new CodeObjectCreateExpression(
						new CodeTypeReference(
							"EventHandler",
							new CodeTypeReference(typeof(WorkflowEventArgs))),
						new CodeMethodReferenceExpression(
							new CodeThisReferenceExpression(), "runtime_WorkflowAborted"))));
			condCleanUp.TrueStatements.Add(
				new CodeRemoveEventStatement(
					new CodePropertyReferenceExpression(
						new CodePropertyReferenceExpression(
							new CodeTypeReferenceExpression(_ctdLocalService.Name),
							"Instance"),
						"Runtime"),
					"WorkflowTerminated",
					new CodeObjectCreateExpression(
						new CodeTypeReference(
							"EventHandler",
							new CodeTypeReference(typeof(WorkflowTerminatedEventArgs))),
						new CodeMethodReferenceExpression(
							new CodeThisReferenceExpression(), "runtime_WorkflowTerminated"))));
			#endregion
			condCleanUp.TrueStatements.Add(
				new CodeAssignStatement(
					new CodeFieldReferenceExpression(
						new CodeThisReferenceExpression(), "_callback"),
					new CodePrimitiveExpression(null)));
			_ctdHostService.Members.Add(mCleanUp);
			CodeMemberMethod mCompleted = new CodeMemberMethod();
			mCompleted.Attributes = MemberAttributes.Private | MemberAttributes.Final;
			mCompleted.Name = "runtime_WorkflowCompleted";
			mCompleted.Parameters.Add(
				new CodeParameterDeclarationExpression(typeof(object), "sender"));
			mCompleted.Parameters.Add(
				new CodeParameterDeclarationExpression(typeof(WorkflowCompletedEventArgs), "e"));
			// cleanup(e.WorkflowInstance.InstanceId);
			mCompleted.Statements.Add(
				new CodeMethodInvokeExpression(
					new CodeThisReferenceExpression(),
					mCleanUp.Name,
					new CodePropertyReferenceExpression(
						new CodePropertyReferenceExpression(
							new CodeArgumentReferenceExpression("e"), "WorkflowInstance"),
						"InstanceId")));
			_ctdHostService.Members.Add(mCompleted);
			CodeMemberMethod mAborted = new CodeMemberMethod();
			mAborted.Attributes = MemberAttributes.Private | MemberAttributes.Final;
			mAborted.Name = "runtime_WorkflowAborted";
			mAborted.Parameters.Add(
				new CodeParameterDeclarationExpression(typeof(object), "sender"));
			mAborted.Parameters.Add(
				new CodeParameterDeclarationExpression(typeof(WorkflowEventArgs), "e"));
			// cleanup(e.WorkflowInstance.InstanceId);
			mAborted.Statements.Add(
				new CodeMethodInvokeExpression(
					new CodeThisReferenceExpression(),
					mCleanUp.Name,
					new CodePropertyReferenceExpression(
						new CodePropertyReferenceExpression(
							new CodeArgumentReferenceExpression("e"), "WorkflowInstance"),
						"InstanceId")));
			_ctdHostService.Members.Add(mAborted);
			CodeMemberMethod mTerminated = new CodeMemberMethod();
			mTerminated.Attributes = MemberAttributes.Private | MemberAttributes.Final;
			mTerminated.Name = "runtime_WorkflowTerminated";
			mTerminated.Parameters.Add(
				new CodeParameterDeclarationExpression(typeof(object), "sender"));
			mTerminated.Parameters.Add(
				new CodeParameterDeclarationExpression(typeof(WorkflowTerminatedEventArgs), "e"));
			// cleanup(e.WorkflowInstance.InstanceId);
			mTerminated.Statements.Add(
				new CodeMethodInvokeExpression(
					new CodeThisReferenceExpression(),
					mCleanUp.Name,
					new CodePropertyReferenceExpression(
						new CodePropertyReferenceExpression(
							new CodeArgumentReferenceExpression("e"), "WorkflowInstance"),
						"InstanceId")));
			_ctdHostService.Members.Add(mTerminated);
			#endregion

			#region create Host Service private field
			_ctdHostService.Members.Add(
				new CodeMemberField(typeof(Guid), "_instanceId"));
			_ctdHostService.Members.Add(
				new CodeMemberField(_ctdInterfaceCallback.Name, "_callback"));
			#endregion

			#endregion

			#region Generate Proxy Class

			#region add static members
			// private static PROXY _instance = new PROXY();
			CodeMemberField fieldInstance = new CodeMemberField();
			fieldInstance.Attributes = MemberAttributes.Private | MemberAttributes.Static;
			fieldInstance.InitExpression = new CodeObjectCreateExpression(_ctdLocalService.Name);
			fieldInstance.Name = "_instance";
			fieldInstance.StartDirectives.Add(new CodeRegionDirective(CodeRegionMode.Start, "Static Members"));
			fieldInstance.EndDirectives.Add(new CodeRegionDirective(CodeRegionMode.End, "Static Members"));
			fieldInstance.Type = new CodeTypeReference(_ctdLocalService.Name);
			_ctdLocalService.Members.Add(fieldInstance);
			// public static PROXY Instance { get {...} }
			CodeMemberProperty propInstance = new CodeMemberProperty();
			propInstance.Attributes = MemberAttributes.Public | MemberAttributes.Static;
			propInstance.StartDirectives.Add(new CodeRegionDirective(CodeRegionMode.Start, "Static Members"));
			propInstance.EndDirectives.Add(new CodeRegionDirective(CodeRegionMode.End, "Static Members"));
			propInstance.GetStatements.Add(
				new CodeMethodReturnStatement(
					new CodeFieldReferenceExpression(
						new CodeTypeReferenceExpression(_ctdLocalService.Name), "_instance")));
			propInstance.HasGet = true;
			propInstance.HasSet = false;
			propInstance.Name = "Instance";
			propInstance.Type = new CodeTypeReference(_ctdLocalService.Name);
			_ctdLocalService.Members.Add(propInstance);
			#endregion

			#region create constructor
			CodeConstructor ctorProxy = new CodeConstructor();
			ctorProxy.Attributes = MemberAttributes.Private;
			ctorProxy.StartDirectives.Add(new CodeRegionDirective(CodeRegionMode.Start, "Initialization"));
			ctorProxy.EndDirectives.Add(new CodeRegionDirective(CodeRegionMode.End, "Initialization"));
			// ExternalDataExchangeService extdatasvc = new ExternalDataExchangeService()
			ctorProxy.Statements.Add(
				new CodeVariableDeclarationStatement(
					typeof(ExternalDataExchangeService),
					Deployment.cExtDataSvc,
					new CodeObjectCreateExpression(typeof(ExternalDataExchangeService))));
			// _wfRuntime = new WorkflowRuntime();
			ctorProxy.Statements.Add(
				new CodeAssignStatement(
					new CodeFieldReferenceExpression(
						new CodeThisReferenceExpression(), Deployment.c_wfRuntime),
					new CodeObjectCreateExpression(typeof(WorkflowRuntime))));
			// _wfRuntime.AddService(extdatasvc);
			ctorProxy.Statements.Add(
				new CodeMethodInvokeExpression(
					new CodeFieldReferenceExpression(
						new CodeThisReferenceExpression(), Deployment.c_wfRuntime),
					Deployment.cAddService,
					new CodeVariableReferenceExpression(Deployment.cExtDataSvc)));
			// _wfRuntime.AddService(new AsyncService());
			ctorProxy.Statements.Add(
				new CodeMethodInvokeExpression(
					new CodeFieldReferenceExpression(
						new CodeThisReferenceExpression(), Deployment.c_wfRuntime),
					Deployment.cAddService,
					new CodeObjectCreateExpression(typeof(AsyncService))));
			// _wfRuntime.StartRuntime();
			ctorProxy.Statements.Add(
				new CodeMethodInvokeExpression(
					new CodeFieldReferenceExpression(
						new CodeThisReferenceExpression(), Deployment.c_wfRuntime),
					Deployment.cStartRuntime));
			// extdatasvc.AddService(this);
			ctorProxy.Statements.Add(
				new CodeMethodInvokeExpression(
					new CodeVariableReferenceExpression(Deployment.cExtDataSvc),
					Deployment.cAddService,
					new CodeThisReferenceExpression()));
			_ctdLocalService.Members.Add(ctorProxy);
			#endregion

			#region add private fields
			_ctdLocalService.Members.Add(
				new CodeMemberField(typeof(WorkflowRuntime), Deployment.c_wfRuntime));
			#endregion

			#region add properties
			CodeMemberProperty propWFRTM = new CodeMemberProperty();
			propWFRTM.Name = Deployment.cRuntime;
			propWFRTM.Attributes = MemberAttributes.Public | MemberAttributes.Final;
			propWFRTM.Type = new CodeTypeReference(typeof(WorkflowRuntime));
			propWFRTM.HasGet = true;
			propWFRTM.HasSet = false;
			propWFRTM.GetStatements.Add(
				new CodeMethodReturnStatement(
					new CodeFieldReferenceExpression(
						new CodeThisReferenceExpression(), Deployment.c_wfRuntime)));
			_ctdLocalService.Members.Add(propWFRTM);
			#endregion

			#region add and implement IDisposable
			// add IDisposable to class
			_ctdLocalService.BaseTypes.Add(typeof(IDisposable));

			// implement Dispose method
			CodeMemberMethod methDispose = new CodeMemberMethod();
			methDispose.Attributes = MemberAttributes.Public | MemberAttributes.Final;
			methDispose.Name = Deployment.cDispose;
			methDispose.StartDirectives.Add(new CodeRegionDirective(CodeRegionMode.Start, "IDisposable Members"));
			methDispose.EndDirectives.Add(new CodeRegionDirective(CodeRegionMode.End, "IDisposable Members"));
			methDispose.Statements.Add(
				new CodeMethodInvokeExpression(
					new CodeFieldReferenceExpression(
						new CodeThisReferenceExpression(), Deployment.c_wfRuntime),
					Deployment.cStopRuntime));
			methDispose.Statements.Add(
				new CodeMethodInvokeExpression(
					new CodeFieldReferenceExpression(
						new CodeThisReferenceExpression(), Deployment.c_wfRuntime),
					Deployment.cDispose));
			methDispose.Statements.Add(
				new CodeAssignStatement(
					new CodeFieldReferenceExpression(
						new CodeThisReferenceExpression(), Deployment.c_wfRuntime),
					new CodePrimitiveExpression(null)));
			_ctdLocalService.Members.Add(methDispose);
			#endregion

			#endregion

			#region Add Events
			foreach ( Repository.WorkflowEvent we in this.Workflow.Interface.Events ) {
				// create ExternalDataEventArgs class for event business object
				CodeTypeReference typeRefBObj;
				string classEventArgsName = createExternalDataEventArgsClass(deployment, typeProvider, we, out typeRefBObj);
				string delegateName = we.Name + Deployment.cEventHandler;

				// create delegate for ExternalDataEventArgs
				createEventDelegate(delegateName, classEventArgsName);

				// add event to interface (public interface I<WFNAME>Local)
				// event XEventHandler NAME;
				CodeMemberEvent interfaceEvent = new CodeMemberEvent();
				interfaceEvent.Name = we.Name;
				interfaceEvent.Type = new CodeTypeReference(delegateName);
				interfaceEvent.Attributes = (MemberAttributes)0;
				// add event to local interface
				_ctdLocalInterface.Members.Add(interfaceEvent);

				// add event to interface implementation (public class <WFNAME>Local : I<WFNAME>Local)
				CodeMemberEvent classEvent = new CodeMemberEvent();
				classEvent.Name = we.Name;
				classEvent.Attributes = MemberAttributes.Final | MemberAttributes.Public;
				classEvent.Type = new CodeTypeReference(delegateName);
				// add event to local service class
				_ctdLocalService.Members.Add(classEvent);

				// add "RaiseEvent" method to interface implementation
				addRaiseEventToInterfaceImplementationForWCF(we, typeRefBObj, classEventArgsName, delegateName);

				// add properties to code beside

				// create workflowInstanceId Property
				_memberCreation.CreateProperty(this.FullClassName,
											   PropertyNames.WorkflowInstanceId,
											   typeof(Guid),
											   null,
											   true,
											   false,
											   false,
											   null,
											   false);

				// add EventArgs property and assign to input property
				if ( typeRefBObj != null ) {
					Type t = typeProvider.GetType(this.Namespace + "." + classEventArgsName);
					_memberCreation.CreatePropertyForWCFInputEventArgs(this.FullClassName,
						classEventArgsName,
						t,
						we.BusinessObjectName, PropertyNames.WorkflowInstanceId);
				}
				#region add event method to wcf service contract
				CodeMemberMethod meth = new CodeMemberMethod();
				meth.Attributes = 0;
				meth.CustomAttributes.Add(
					new CodeAttributeDeclaration(
						new CodeTypeReference(typeof(OperationContractAttribute)),
						new CodeAttributeArgument("IsOneWay", new CodePrimitiveExpression(true))));
				meth.Name = we.Name;
				if ( typeRefBObj != null ) {
					meth.Parameters.Add(
						new CodeParameterDeclarationExpression(typeRefBObj, "input"));
				}
				_ctdInterface.Members.Add(meth);
				#endregion

				#region add event method implementation to host service
				CodeMemberMethod methImpl = new CodeMemberMethod();
				methImpl.Attributes = MemberAttributes.Public | MemberAttributes.Final;
				methImpl.Name = we.Name;
				if ( typeRefBObj != null ) {
					methImpl.Parameters.Add(
						new CodeParameterDeclarationExpression(typeRefBObj, "input"));
				}
				methImpl.Statements.Add(
					new CodeConditionStatement(
						new CodeBinaryOperatorExpression(
							new CodeFieldReferenceExpression(
								new CodeThisReferenceExpression(), "_callback"),
							CodeBinaryOperatorType.IdentityEquality,
							new CodePrimitiveExpression(null)),
						new CodeAssignStatement(
							new CodeFieldReferenceExpression(
								new CodeThisReferenceExpression(), "_callback"),
							new CodeMethodInvokeExpression(
								new CodeMethodReferenceExpression(
									new CodePropertyReferenceExpression(
										new CodeTypeReferenceExpression(typeof(OperationContext)),
										"Current"),
									"GetCallbackChannel",
									new CodeTypeReference(_ctdInterfaceCallback.Name))))));
				CodeMethodInvokeExpression invokeRaise = new CodeMethodInvokeExpression();
				invokeRaise.Method = new CodeMethodReferenceExpression(
					new CodePropertyReferenceExpression(
						new CodeTypeReferenceExpression(_ctdLocalService.Name),
						"Instance"),
					"Raise" + we.Name);
				if ( typeRefBObj != null ) {
					invokeRaise.Parameters.Add(new CodeArgumentReferenceExpression("input"));
				}
				if ( we.IsStart ) {
					methImpl.Statements.Add(
						new CodeAssignStatement(
							new CodeFieldReferenceExpression(
								new CodeThisReferenceExpression(), "_instanceId"),
							invokeRaise));
				} else {
					invokeRaise.Parameters.Add(
						new CodeFieldReferenceExpression(
							new CodeThisReferenceExpression(), "_instanceId"));
					methImpl.Statements.Add(invokeRaise);
				}
				_ctdHostService.Members.Add(methImpl);
				#endregion
			}
			#endregion

			#region Add Methods
			foreach ( Repository.WorkflowMethod wm in this.Workflow.Interface.Methods ) {
				CodeTypeReference typeRefInput, typeRefOutput;
				// create EventArgs class for interface method implementation
				string classEventArgsName = createEventArgsClass(deployment, typeProvider, wm,
					out typeRefInput, out typeRefOutput);
				string delegateName = wm.Name + Deployment.cEventHandler;

				// create delegate for EventArgs
				if ( string.IsNullOrEmpty(classEventArgsName) ) {
					classEventArgsName = wm.Name + Deployment.cEventArgs;
				} else {
					createEventDelegate(delegateName, classEventArgsName);
				}

				// add method to interface
				CodeMemberMethod interfaceMethod = new CodeMemberMethod();
				interfaceMethod.Name = wm.Name;
				interfaceMethod.Attributes = MemberAttributes.Public;
				interfaceMethod.Parameters.Add(
					new CodeParameterDeclarationExpression(typeof(Guid), "workflowInstanceId"));
				if ( typeRefInput != null ) {
					// add process output parameter
					interfaceMethod.Parameters.Add(
						new CodeParameterDeclarationExpression(typeRefInput, Deployment.cMethodInput));
				}
				if ( typeRefOutput != null ) {
					// set return value
					interfaceMethod.ReturnType = typeRefOutput;
				}
				// add output method to interface
				_ctdLocalInterface.Members.Add(interfaceMethod);

				// add event to interface implementation class
				CodeMemberEvent classEvent = new CodeMemberEvent();
				classEvent.Name = wm.Name + Deployment.cEvent;
				classEvent.Attributes = MemberAttributes.Final | MemberAttributes.Public;
				classEvent.Type = new CodeTypeReference(delegateName);
				// add event to local service class
				_ctdLocalService.Members.Add(classEvent);

				// add method implementation to invoke the created event
				addMethodToInterfaceImplementation(wm, typeRefInput, typeRefOutput,
												   classEventArgsName, delegateName);

				#region add method to wcf service callback contract
				CodeMemberMethod meth = new CodeMemberMethod();
				meth.Attributes = 0;
				if ( typeRefOutput != null ) {
					meth.CustomAttributes.Add(
						new CodeAttributeDeclaration(
							new CodeTypeReference(typeof(OperationContractAttribute))));
					meth.ReturnType = typeRefOutput;
				} else {
					meth.CustomAttributes.Add(
						new CodeAttributeDeclaration(
							new CodeTypeReference(typeof(OperationContractAttribute)),
							new CodeAttributeArgument("IsOneWay", new CodePrimitiveExpression(true))));
				}
				meth.Name = wm.Name;
				if ( typeRefInput != null ) {
					meth.Parameters.Add(
						new CodeParameterDeclarationExpression(typeRefInput, Deployment.cMethodOutput));
				}
				_ctdInterfaceCallback.Members.Add(meth);
				#endregion

				#region add method implementation to host service
				// attach event
				ctorHost.Statements.Add(
					new CodeAttachEventStatement(
						new CodePropertyReferenceExpression(
							new CodeTypeReferenceExpression(_ctdLocalService.Name), "Instance"),
						classEvent.Name,
						new CodeObjectCreateExpression(
							delegateName,
							new CodeMethodReferenceExpression(
								new CodeThisReferenceExpression(), "proxy_" + classEvent.Name))));
				// remove event handler on cleanup
				condCleanUp.TrueStatements.Add(
					new CodeRemoveEventStatement(
						new CodePropertyReferenceExpression(
							new CodeTypeReferenceExpression(_ctdLocalService.Name), "Instance"),
						classEvent.Name,
						new CodeObjectCreateExpression(
							delegateName,
							new CodeMethodReferenceExpression(
								new CodeThisReferenceExpression(), "proxy_" + classEvent.Name))));
				// create event handler method
				CodeMemberMethod methEventHandler = new CodeMemberMethod();
				methEventHandler.Attributes = MemberAttributes.Private | MemberAttributes.Final;
				methEventHandler.Name = "proxy_" + classEvent.Name;
				methEventHandler.Parameters.Add(
					new CodeParameterDeclarationExpression(typeof(object), "sender"));
				methEventHandler.Parameters.Add(
					new CodeParameterDeclarationExpression(classEventArgsName, "e"));

				CodeConditionStatement condIsInstance = new CodeConditionStatement();
				condIsInstance.Condition =
					new CodeBinaryOperatorExpression(
						new CodePropertyReferenceExpression(
							new CodeArgumentReferenceExpression("e"), "InstanceId"),
						CodeBinaryOperatorType.IdentityEquality,
						new CodeFieldReferenceExpression(
							new CodeThisReferenceExpression(), "_instanceId"));
				CodeMethodInvokeExpression invokeWM = new CodeMethodInvokeExpression();
				invokeWM.Method = new CodeMethodReferenceExpression(
					new CodeFieldReferenceExpression(
						new CodeThisReferenceExpression(), "_callback"), wm.Name);
				if ( typeRefInput != null ) {
					invokeWM.Parameters.Add(
						new CodePropertyReferenceExpression(
							new CodeArgumentReferenceExpression("e"), Deployment.cPropMethodInput));
				}
				if ( typeRefOutput != null ) {
					condIsInstance.TrueStatements.Add(
						new CodeAssignStatement(
							new CodePropertyReferenceExpression(
								new CodeArgumentReferenceExpression("e"),
								Deployment.cPropMethodOutput),
							invokeWM));
				} else {
					condIsInstance.TrueStatements.Add(invokeWM);
				}
				methEventHandler.Statements.Add(condIsInstance);

				_ctdHostService.Members.Add(methEventHandler);
				#endregion
			}
			#endregion
		}

		/// <summary>
		/// Creates a delegate for the EventArgs class.<br/>
		/// ( public delegate void delegateName(object sender, eventArgsClassName e); )
		/// </summary>
		/// <param name="delegateName">The name of the delegate.</param>
		/// <param name="eventArgsClassName">The name of the type for the parameter 'e'.</param>
		private void createEventDelegate(string delegateName, string eventArgsClassName)
		{
			CodeTypeDelegate delegateEvent = new CodeTypeDelegate();
			delegateEvent.Name = delegateName;
			delegateEvent.Attributes = MemberAttributes.Public | MemberAttributes.Final;
			delegateEvent.Parameters.Add(
				new CodeParameterDeclarationExpression(typeof(object), "sender"));
			delegateEvent.Parameters.Add(
				new CodeParameterDeclarationExpression(eventArgsClassName, "e"));
			// add delegate to namespace
			_nsLocalService.Types.Add(delegateEvent);
		}
		/// <summary>
		/// Creates an ExternalDataEventArgs class for the Business Object of the WorkflowEvent we.
		/// </summary>
		/// <param name="typeProvider">A TypeProvider.</param>
		/// <param name="we">A Workflow Event.</param>
		/// <returns>The name of the generated class.</returns>
		private string createExternalDataEventArgsClass(
			Deployment deployment,
			TypeProvider typeProvider, WorkflowEvent we,
			out CodeTypeReference typeRefBObj)
		{
			typeRefBObj = null;
			if ( we.BusinessObjectID <= 0 ) {
				// no business object assigned
				return Deployment.cExternalDataEventArgs;
				// RETURN
			}
			string classEventArgsName = we.BusinessObjectName + Deployment.cExternalDataEventArgs;

			Type typeEEA = typeProvider.GetType(this.Namespace + "." + classEventArgsName);
			if ( typeEEA != null ) {
				typeRefBObj = new CodeTypeReference(
					typeProvider.GetType(this.NamespaceData + "." + we.BusinessObjectName));
				return classEventArgsName;
			}
			if ( typeRefBObj == null ) {
				// add WorkflowEvent Business Object
				deployment.AddBusinessObjectToDataCode(ccuData, this.NamespaceData, typeProvider,
					we.BusinessObject, true);

				typeRefBObj = new CodeTypeReference(
					typeProvider.GetType(this.NamespaceData + "." + we.BusinessObjectName));
				// add property for business object to code beside
				if ( typeRefBObj != null ) {
					addPropertyForBObjectToCodeBeside(typeProvider, we.BusinessObject, typeRefBObj);
				}
			}
			CodeTypeDeclaration ctdExtEventArgs = new CodeTypeDeclaration(classEventArgsName);
			ctdExtEventArgs.Attributes = MemberAttributes.Public | MemberAttributes.Final;
			//	add SerializableAttribute
			ctdExtEventArgs.CustomAttributes.Add(
				new CodeAttributeDeclaration(new CodeTypeReference(typeof(SerializableAttribute))));
			//	add Base Class
			ctdExtEventArgs.BaseTypes.Add(typeof(ExternalDataEventArgs));
			//	add Constuctor
			CodeConstructor ctorEventArgs = new CodeConstructor();
			ctorEventArgs.Attributes = MemberAttributes.Final | MemberAttributes.Public;
			ctorEventArgs.Parameters.Add(	// XExternalDataEventArgs(Guid instanceId, ...)
				new CodeParameterDeclarationExpression(typeof(Guid), "instanceId"));
			//			: base(instanceId);
			ctorEventArgs.BaseConstructorArgs.Add(new CodeArgumentReferenceExpression("instanceId"));

			if ( typeRefBObj != null ) {
				ctorEventArgs.Parameters.Add(	// XExternalDataEventArgs(..., InputType input)
					new CodeParameterDeclarationExpression(typeRefBObj, "input"));
				ctorEventArgs.Statements.Add(	// _input = input;
					new CodeAssignStatement(
						new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), "_input"),
						new CodeArgumentReferenceExpression("input")));
			}
			ctdExtEventArgs.Members.Add(ctorEventArgs);
			if ( typeRefBObj != null ) {
				//	add private input data field
				ctdExtEventArgs.Members.Add(
					new CodeMemberField(typeRefBObj, "_input"));
				//	add public input data property (get)
				CodeMemberProperty propInput = new CodeMemberProperty();
				propInput.Name = "Input";
				propInput.Attributes = MemberAttributes.Public | MemberAttributes.Final;
				propInput.Type = typeRefBObj;
				propInput.HasGet = true;
				propInput.HasSet = false;
				propInput.GetStatements.Add(
					new CodeMethodReturnStatement(
						new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), "_input")));

				ctdExtEventArgs.Members.Add(propInput);
			}
			// add EventArgs class to namespace
			_nsLocalService.Types.Add(ctdExtEventArgs);

			refreshTypeProvider(ref typeProvider, ref ccuLocalService);

			return classEventArgsName;
		}
		private string createEventArgsClass(
			Deployment deployment,
			TypeProvider typeProvider, WorkflowMethod wm,
			out CodeTypeReference typeRefInput, out CodeTypeReference typeRefOutput)
		{
			#region Initialization
			typeRefInput = null;
			typeRefOutput = null;
			string classEventArgsName = wm.Name + Deployment.cEventArgs;
			Type typeEEA = typeProvider.GetType(classEventArgsName);
			if ( typeEEA != null ) {
				if ( wm.InputBusinessObjectID > 0 ) {
					typeRefInput = new CodeTypeReference(
						typeProvider.GetType(this.NamespaceData + "." + wm.InputBusinessObjectName));
				}
				if ( wm.OutputBusinessObjectID > 0 ) {
					typeRefOutput = new CodeTypeReference(
						typeProvider.GetType(this.NamespaceData + "." + wm.OutputBusinessObjectName));
				}
				return null;
			}
			#endregion

			#region Add WorkflowEvent Input/Output Business Objects to Data code
			if ( wm.InputBusinessObjectID > 0 ) {
				deployment.AddBusinessObjectToDataCode(ccuData, this.NamespaceData, typeProvider, wm.InputBusinessObject, true);
				typeRefInput = new CodeTypeReference(
					typeProvider.GetType(this.NamespaceData + "." + wm.InputBusinessObjectName));
			}
			if ( wm.OutputBusinessObjectID > 0 ) {
				deployment.AddBusinessObjectToDataCode(ccuData, this.NamespaceData, typeProvider, wm.OutputBusinessObject, true);
				typeRefOutput = new CodeTypeReference(
					typeProvider.GetType(this.NamespaceData + "." + wm.OutputBusinessObjectName));
			}
			#endregion

			#region Add Properties for Input/Output Business Objects to Code Beside
			// add property for input business object to code beside
			if ( typeRefInput != null ) {
				addPropertyForBObjectToCodeBeside(typeProvider, wm.InputBusinessObject, typeRefInput);
			}

			// add property for output business object to code beside
			if ( typeRefOutput != null ) {
				addPropertyForBObjectToCodeBeside(typeProvider, wm.OutputBusinessObject, typeRefOutput);
			}
			#endregion

			#region Initialize Method EventArgs Class
			CodeTypeDeclaration ctdEventArgs = new CodeTypeDeclaration(classEventArgsName);
			ctdEventArgs.Attributes = MemberAttributes.Public | MemberAttributes.Final;
			//	add SerializableAttribute
			ctdEventArgs.CustomAttributes.Add(
				new CodeAttributeDeclaration(new CodeTypeReference(typeof(SerializableAttribute))));
			//	add Base Class
			ctdEventArgs.BaseTypes.Add(typeof(EventArgs));
			#endregion

			#region	Add Constuctor
			CodeConstructor ctorEventArgs = new CodeConstructor();
			ctorEventArgs.Attributes = MemberAttributes.Final | MemberAttributes.Public;
			ctorEventArgs.Parameters.Add(	// XEventArgs(Guid instanceId, ...)
				new CodeParameterDeclarationExpression(typeof(Guid), Deployment.cInstanceId));
			// this._instanceId = instanceId;
			ctorEventArgs.Statements.Add(
				new CodeAssignStatement(
					new CodeFieldReferenceExpression(
						new CodeThisReferenceExpression(), Deployment.c_InstanceId),
					new CodeArgumentReferenceExpression(Deployment.cInstanceId)));
			if ( typeRefInput != null ) {
				ctorEventArgs.Parameters.Add(	// XEventArgs(..., InputType methodInput)
					new CodeParameterDeclarationExpression(typeRefInput, Deployment.cMethodInput));
				ctorEventArgs.Statements.Add(	// _methodInput = methodInput;
					new CodeAssignStatement(
						new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), Deployment.c_MethodInput),
						new CodeArgumentReferenceExpression(Deployment.cMethodInput)));
			}
			if ( typeRefOutput != null ) {
				ctorEventArgs.Statements.Add(	// _returnValue = null;
					new CodeAssignStatement(
						new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), Deployment.c_MethodOutput),
						new CodePrimitiveExpression(null)));
			}
			ctdEventArgs.Members.Add(ctorEventArgs);
			#endregion

			#region Add Properties and Backing Fields

			#region Instance Id
			ctdEventArgs.Members.Add(
				new CodeMemberField(typeof(Guid), Deployment.c_InstanceId));
			CodeMemberProperty propInstId = new CodeMemberProperty();
			propInstId.Attributes = MemberAttributes.Public | MemberAttributes.Final;
			propInstId.GetStatements.Add(
				new CodeMethodReturnStatement(
					new CodeFieldReferenceExpression(
						new CodeThisReferenceExpression(), Deployment.c_InstanceId)));
			propInstId.HasGet = true;
			propInstId.HasSet = false;
			propInstId.Name = Deployment.cPropInstanceId;
			propInstId.Type = new CodeTypeReference(typeof(Guid));
			ctdEventArgs.Members.Add(propInstId);
			#endregion
			#region Process Output
			if ( typeRefInput != null ) {
				//	add private output data field
				ctdEventArgs.Members.Add(
					new CodeMemberField(typeRefInput, Deployment.c_MethodInput));
				//	add public output data property (get)
				CodeMemberProperty propOutput = new CodeMemberProperty();
				propOutput.Name = Deployment.cPropMethodInput;
				propOutput.Attributes = MemberAttributes.Public | MemberAttributes.Final;
				propOutput.Type = typeRefInput;
				propOutput.HasGet = true;
				propOutput.HasSet = false;
				propOutput.GetStatements.Add(
					new CodeMethodReturnStatement(
						new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), Deployment.c_MethodInput)));

				ctdEventArgs.Members.Add(propOutput);
			}
			#endregion
			#region Method Return Value
			if ( typeRefOutput != null ) {
				//	add private input data field
				ctdEventArgs.Members.Add(
					new CodeMemberField(typeRefOutput, Deployment.c_MethodOutput));
				//	add public input data property (get)
				CodeMemberProperty propInput = new CodeMemberProperty();
				propInput.Name = Deployment.cPropMethodOutput;
				propInput.Attributes = MemberAttributes.Public | MemberAttributes.Final;
				propInput.Type = typeRefOutput;
				propInput.HasGet = true;
				propInput.GetStatements.Add(
					new CodeMethodReturnStatement(
						new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), Deployment.c_MethodOutput)));
				propInput.HasSet = true;
				propInput.SetStatements.Add(
					new CodeAssignStatement(
						new CodeFieldReferenceExpression(
							new CodeThisReferenceExpression(), Deployment.c_MethodOutput),
						new CodePropertySetValueReferenceExpression()));

				ctdEventArgs.Members.Add(propInput);
			}
			#endregion

			#endregion

			// add EventArgs class to namespace
			_nsLocalService.Types.Add(ctdEventArgs);

			return classEventArgsName;
		}

		private void addRaiseEventToInterfaceImplementation(Repository.WorkflowEvent we,
			CodeTypeReference typeRefBObj, string classEventArgsName, string delegateName)
		{
			string summary = "";
			CodeMemberMethod methodRaiseEvent = new CodeMemberMethod();
			methodRaiseEvent.Attributes = MemberAttributes.Public | MemberAttributes.Final;
			methodRaiseEvent.Name = Deployment.cRaise + we.Name;
			if ( !string.IsNullOrEmpty(we.Description) ) {
				summary = we.Description;
			}
			if ( typeRefBObj != null ) {
				methodRaiseEvent.Parameters.Add(
					new CodeParameterDeclarationExpression(typeRefBObj, Deployment.cInput));
			}
			if ( we.IsStart ) {
				if ( string.IsNullOrEmpty(summary) ) {
					summary = "Use this method to start a new workflow instance.";
				} else {
					summary = string.Format("{0}{1} {2}",
						"Use this method to start a new workflow instance.", Environment.NewLine, summary);
				}
				methodRaiseEvent.Statements.Add(
					new CodeCommentStatement("create and start new workflow instance"));
				// _wfInstance = _wfRuntime.CreateWorkflow(typeof(<WFNAME>));
				methodRaiseEvent.Statements.Add(
					new CodeAssignStatement(
						new CodeFieldReferenceExpression(
							new CodeThisReferenceExpression(), Deployment.c_wfInstance),
						new CodeMethodInvokeExpression(
							new CodeFieldReferenceExpression(
								new CodeThisReferenceExpression(), Deployment.c_wfRuntime),
							Deployment.cCreateWorkflow,
							new CodeTypeOfExpression(this.FullClassName))));
				// _wfInstance.Start();
				methodRaiseEvent.Statements.Add(
					new CodeExpressionStatement(
						new CodeMethodInvokeExpression(
							new CodeFieldReferenceExpression(
								new CodeThisReferenceExpression(), Deployment.c_wfInstance),
							Deployment.cStart)));
			} else {
				methodRaiseEvent.Statements.Add(
					new CodeConditionStatement(
					// if ( _wfInstance == null )
						new CodeBinaryOperatorExpression(
							new CodeFieldReferenceExpression(
								new CodeThisReferenceExpression(), Deployment.c_wfInstance),
							CodeBinaryOperatorType.ValueEquality,
							new CodePrimitiveExpression(null)),
						new CodeStatement[] {
							// throw new NullReferenceException("First use a raise start event method to create a new workflow instance.");
							new CodeThrowExceptionStatement(
								new CodeObjectCreateExpression(
									typeof(NullReferenceException),
									new CodePrimitiveExpression("First use a raise start event method to create a new workflow instance.")))
						}));
			}
			if ( !string.IsNullOrEmpty(summary) ) {
				methodRaiseEvent.Comments.Add(new CodeCommentStatement(
					string.Format("<summary>{0} {1}{0} </summary>", Environment.NewLine, summary),
					true));
			}
			// XEventArgs e = new XEventArgs(workflowInstanceId[, input]);
			CodeObjectCreateExpression createE = new CodeObjectCreateExpression();
			createE.CreateType = new CodeTypeReference(classEventArgsName);
			createE.Parameters.Add(
				new CodePropertyReferenceExpression(
					new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), Deployment.c_wfInstance),
					"InstanceId"));
			if ( typeRefBObj != null ) {
				createE.Parameters.Add(new CodeArgumentReferenceExpression(Deployment.cInput));
			}
			methodRaiseEvent.Statements.Add(
				new CodeVariableDeclarationStatement(
					classEventArgsName,
					"e",
					createE));
			// XEventHandler tmp = this.StartOp;
			methodRaiseEvent.Statements.Add(
				new CodeVariableDeclarationStatement(
					delegateName,
					"tmp",
					new CodeEventReferenceExpression(new CodeThisReferenceExpression(), we.Name)));
			// if ( tmp != null )
			methodRaiseEvent.Statements.Add(
				new CodeConditionStatement(
					new CodeBinaryOperatorExpression(
						new CodeVariableReferenceExpression("tmp"),
						CodeBinaryOperatorType.IdentityInequality,
						new CodePrimitiveExpression(null)),
					new CodeStatement[] {
						new CodeExpressionStatement(
						new CodeDelegateInvokeExpression( // tmp(this, e);
							new CodeVariableReferenceExpression("tmp"),
							new CodePrimitiveExpression(null),
							new CodeVariableReferenceExpression("e")))
					}));
			_ctdLocalService.Members.Add(methodRaiseEvent);
		}
		private void addRaiseEventToInterfaceImplementationForWCF(Repository.WorkflowEvent we,
			CodeTypeReference typeRefBObj, string classEventArgsName, string delegateName)
		{
			string summary = "";
			CodeMemberMethod methodRaiseEvent = new CodeMemberMethod();
			methodRaiseEvent.Attributes = MemberAttributes.Public | MemberAttributes.Final;
			methodRaiseEvent.Name = Deployment.cRaise + we.Name;
			if ( !string.IsNullOrEmpty(we.Description) ) {
				summary = we.Description;
			}
			if ( typeRefBObj != null ) {
				methodRaiseEvent.Parameters.Add(
					new CodeParameterDeclarationExpression(typeRefBObj, Deployment.cInput));
			}
			if ( we.IsStart ) {
				if ( string.IsNullOrEmpty(summary) ) {
					summary = "Use this method to start a new workflow instance.";
				} else {
					summary = string.Format("{0}{1} {2}",
						"Use this method to start a new workflow instance.", Environment.NewLine, summary);
				}
				methodRaiseEvent.Statements.Add(
					new CodeCommentStatement("create and start new workflow instance"));
				methodRaiseEvent.Statements.Add(
					new CodeVariableDeclarationStatement(
						typeof(WorkflowInstance), "wfInstance",
						new CodeMethodInvokeExpression(
							new CodeFieldReferenceExpression(
								new CodeThisReferenceExpression(), Deployment.c_wfRuntime),
							Deployment.cCreateWorkflow,
							new CodeTypeOfExpression(this.FullClassName))));
				methodRaiseEvent.Statements.Add(
					new CodeExpressionStatement(
						new CodeMethodInvokeExpression(
							new CodeVariableReferenceExpression("wfInstance"),
							Deployment.cStart)));

				methodRaiseEvent.ReturnType = new CodeTypeReference(typeof(Guid));
			} else {
				methodRaiseEvent.Parameters.Add(
					new CodeParameterDeclarationExpression(typeof(Guid), "instanceId"));
			}
			if ( !string.IsNullOrEmpty(summary) ) {
				methodRaiseEvent.Comments.Add(new CodeCommentStatement(
					string.Format("<summary>{0} {1}{0} </summary>", Environment.NewLine, summary),
					true));
			}
			// XEventArgs e = new XEventArgs(workflowInstanceId[, input]);
			CodeObjectCreateExpression createE = new CodeObjectCreateExpression();
			createE.CreateType = new CodeTypeReference(classEventArgsName);
			if ( we.IsStart ) {
				createE.Parameters.Add(
					new CodePropertyReferenceExpression(
						new CodeVariableReferenceExpression("wfInstance"),
						"InstanceId"));
			} else {
				createE.Parameters.Add(new CodeArgumentReferenceExpression("instanceId"));
			}
			if ( typeRefBObj != null ) {
				createE.Parameters.Add(new CodeArgumentReferenceExpression(Deployment.cInput));
			}
			methodRaiseEvent.Statements.Add(
				new CodeVariableDeclarationStatement(
					classEventArgsName, "e", createE));
			// XEventHandler tmp = this.StartOp;
			methodRaiseEvent.Statements.Add(
				new CodeVariableDeclarationStatement(
					delegateName, "tmp",
					new CodeEventReferenceExpression(new CodeThisReferenceExpression(), we.Name)));
			// if ( tmp != null )
			methodRaiseEvent.Statements.Add(
				new CodeConditionStatement(
					new CodeBinaryOperatorExpression(
						new CodeVariableReferenceExpression("tmp"),
						CodeBinaryOperatorType.IdentityInequality,
						new CodePrimitiveExpression(null)),
					new CodeStatement[] {
						new CodeExpressionStatement(
						new CodeDelegateInvokeExpression( // tmp(this, e);
							new CodeVariableReferenceExpression("tmp"),
							new CodePrimitiveExpression(null),
							new CodeVariableReferenceExpression("e")))
					}));
			if ( we.IsStart ) {
				// return wfInstance.InstanceId;
				methodRaiseEvent.Statements.Add(
					new CodeMethodReturnStatement(
						new CodePropertyReferenceExpression(
							new CodeVariableReferenceExpression("wfInstance"),
							"InstanceId")));
			}
			_ctdLocalService.Members.Add(methodRaiseEvent);
		}

		private void addMethodToInterfaceImplementation(Repository.WorkflowMethod wm,
			CodeTypeReference typeRefInput, CodeTypeReference typeRefOutput,
			string classEventArgsName, string delegateName)
		{
			CodeMemberMethod method = new CodeMemberMethod();
			method.Attributes = MemberAttributes.Public | MemberAttributes.Final;
			method.Name = wm.Name;
			method.Parameters.Add(
				new CodeParameterDeclarationExpression(typeof(Guid), Deployment.cWorkflowInstanceId));
			if ( typeRefInput != null ) {
				method.Parameters.Add(
					new CodeParameterDeclarationExpression(typeRefInput, Deployment.cMethodInput));
			}
			if ( typeRefOutput != null ) {
				method.ReturnType = typeRefOutput;
			}
			// XEventArgs e = new XEventArgs(workflowInstanceId[, input]);
			CodeObjectCreateExpression createE = new CodeObjectCreateExpression();
			createE.CreateType = new CodeTypeReference(classEventArgsName);
			createE.Parameters.Add(new CodeArgumentReferenceExpression(Deployment.cWorkflowInstanceId));
			if ( typeRefInput != null ) {
				createE.Parameters.Add(new CodeArgumentReferenceExpression(Deployment.cMethodInput));
			}
			method.Statements.Add(
				new CodeVariableDeclarationStatement(
					classEventArgsName,
					"e",
					createE));
			// initialize e.MethodOutput
			if ( typeRefOutput != null ) {
				method.Statements.Add(
					new CodeAssignStatement(
						new CodePropertyReferenceExpression(
							new CodeVariableReferenceExpression("e"), Deployment.cPropMethodOutput),
						new CodeObjectCreateExpression(typeRefOutput)));
			}
			// XEventHandler tmp = this.MethodEvent;
			method.Statements.Add(
				new CodeVariableDeclarationStatement(
					delegateName,
					"tmp",
					new CodeEventReferenceExpression(new CodeThisReferenceExpression(), wm.Name + Deployment.cEvent)));
			// if ( tmp != null )
			method.Statements.Add(
				new CodeConditionStatement(
					new CodeBinaryOperatorExpression(
						new CodeVariableReferenceExpression("tmp"),
						CodeBinaryOperatorType.IdentityInequality,
						new CodePrimitiveExpression(null)),
					new CodeStatement[] {
						new CodeExpressionStatement(
						new CodeDelegateInvokeExpression( // tmp(this, e);
							new CodeVariableReferenceExpression("tmp"),
							new CodePrimitiveExpression(null),
							new CodeVariableReferenceExpression("e")))
					}));
			if ( typeRefOutput != null ) {
				method.Statements.Add(
					new CodeMethodReturnStatement(
						new CodePropertyReferenceExpression(
							new CodeVariableReferenceExpression("e"), Deployment.cPropMethodOutput)));
			}
			_ctdLocalService.Members.Add(method);
		}

		#endregion

		#region Logical Capability Activity
		/// <summary>
		/// Generates the logical capability activity code.
		/// </summary>
		/// <param name="act">The activity.</param>
		/// <param name="host">The designer host.</param>
		/// <param name="repSvc">The repository service.</param>
		/// <param name="deployment">The deployment service.</param>
		/// <param name="dicWebServiceIDEPConfigName">A dictionary with the endpoint configuration names of the web services.</param>
		/// <param name="typeProvider">The type provider.</param>
		/// <param name="doContinue">if set to <c>true</c> continue with the next activity immediately .</param>
		/// <returns></returns>
		private ServiceGenerationType generateLogicalCapabilityActivityCode(
			Activity act, IDesignerHost host, RepositoryService repSvc, Deployment deployment,
			Dictionary<int, string> dicWebServiceIDEPConfigName,
			ref TypeProvider typeProvider, out bool doContinue)
		{
			ServiceGenerationType currentSvcGenType;
			bool isHumanActivity = false;
			bool useProxy = false;
			string endpointConfigName = null;

			currentSvcGenType = ServiceGenerationType.Unknown;
			doContinue = false;

			CodeTypeReference typeRefLogActContract = null;

			// get logical activity
			LogicalCapabilityActivity logcap = (LogicalCapabilityActivity)act;
			if ( logcap.LogicalActivityId <= 0 ) {
				doContinue = true;
				return currentSvcGenType;
			}
			if ( logcap.ActivitiesClass == null ) {
				IDesigner idesigner = null;
				if ( host != null ) idesigner = (IDesigner)host.GetDesigner(logcap);
				ActivityBind actbindIn = new ActivityBind(this.ClassName, "LogicalActivitiesClass");
				logcap.SetBinding(LogicalCapabilityActivity.ActivitiesClassProperty, actbindIn);
				if ( idesigner != null ) idesigner.Initialize(logcap);
			}
			if ( existsLogicalActivityMethod(logcap.LogicalActivityName) ) {
				doContinue = true;
				return currentSvcGenType;
			}
			Repository.LogicalActivity logact =
				repSvc.GetItem<Repository.LogicalActivity>(logcap.LogicalActivityId);
			if ( logact == null ) {
				logcap.LogicalActivityId = -1;
				logcap.LogicalActivityName = "";
				Helpers.SetActivityProperty(logcap, "Capability", null);
				throw new Exception("Please reassign this activity to a capability.");
			}
			if ( logact.VerbID <= 0 ) {
				logcap.LogicalActivityId = -1;
				logcap.LogicalActivityName = "";
				Helpers.SetActivityProperty(logcap, "Capability", null);
				throw new Exception("Please reassign this activity to a capability.");
				//continue;
			}
			if ( logact.WorkflowID != this.Workflow.ID ) {
				logact.WorkflowID = this.Workflow.ID;
				logact.Save();
			}
			logcap.LogicalActivityName = logact.Name;

			// get logical operation
			//Repository.Operation op = logact.GetAssignedOperation();
			// get logical capability
			Repository.Verb verb = logact.Verb;
			// get logical method
			Repository.LogicalWebMethod logwmeth = logact.LogicalMethod;
			// webservice/method
			Repository.WebMethod webmeth = null;
			Repository.WebMethod webmethCallback = null;
			Repository.WebService websvc = null;
			// human activity
			Repository.HumanActivity hact = null;
			List<LogicalRuleResultEPInfos> lstLogRuleResultEPInfos =
								new List<LogicalRuleResultEPInfos>();

			if ( verb != null ) {
				logcap.Capability = verb.Name;
			} else {
				logcap.Capability = "";
			}

			#region initialize rule endpoints, webservice, webmethod and human activity
			if ( logwmeth != null ) {
				if ( logwmeth.IsAssignedTo == LogicalMethodAssignedTo.EndpointRule ) {
					if ( !this.RuleIDs.Contains(logwmeth.EndpointRuleID) ) {
						this.RuleIDs.Add(logwmeth.EndpointRuleID);
					}
					BindingListEx<LogicalRuleResultEndpoint> lstEPs =
										logwmeth.GetLogicalRuleResultEndpoints();
					if ( lstEPs != null ) {
						foreach ( var item in lstEPs ) {
							lstLogRuleResultEPInfos
								.Add(new LogicalRuleResultEPInfos(item));
						}
					}
					hact = null;
					useProxy = false;
				} else {
					if ( logwmeth.ProxyWebMethodID > 0 ) {
						websvc = logwmeth.GetAssignedProxyWebService();
						webmeth = logwmeth.GetAssignedProxyWebMethod();
						webmethCallback = logwmeth.GetProxyCallbackWebMethod();
						hact = null;
						useProxy = true;
					} else {
						websvc = logwmeth.GetAssignedWebService();
						webmeth = logwmeth.GetAssignedWebMethod();
						webmethCallback = logwmeth.GetCallbackWebMethod();
						hact = logwmeth.GetAssignedHumanActivity();//logact.GetHumanActivity();
					}
				}
			} else {
				websvc = logact.GetWebService();
				webmeth = logact.GetWebMethod();
				webmethCallback = null;// logwmeth.GetCallbackWebMethod();
				hact = logact.GetHumanActivity();
			}

			// create process_activity for HumanComponent
			if ( hact != null ) {
				websvc = hact.WebService;
				if ( websvc != null ) addHumanActivity(logact, websvc.Uri);
				isHumanActivity = true;
				this.Workflow.ExtendedProperties.HasHumanActivity = true;
			}

			currentSvcGenType = ServiceGenerationType.Unknown;
			if ( websvc != null ) {
				// set current ServiceGenerationType
				if ( websvc.Type == WebService.ServiceType.APIService ) {
					currentSvcGenType = ServiceGenerationType.APIService;
				} else if ( isHumanActivity ) {
					currentSvcGenType = ServiceGenerationType.HumanActivityService;
				} else if ( websvc.Uri.ToLower().EndsWith(".asmx") ) {
					currentSvcGenType = ServiceGenerationType.SystemWebService;
				} else if ( websvc.Uri.ToLower().EndsWith(".svc") ) {
					currentSvcGenType = ServiceGenerationType.WCFService;
				} else {
					currentSvcGenType = ServiceGenerationType.Unknown;
				}
				// get result web method
				if ( currentSvcGenType == ServiceGenerationType.HumanActivityService ) {
					BindingListEx<Repository.WebMethod> lstWMResult =
										Global.Data.GetRepositoryHierarchyChildRepositoryList<Repository.WebMethod>(
							OpenComposite.EII.Repository.ItemType.WebService, websvc.ID, OpenComposite.EII.Repository.ItemType.WebMethod);
					if ( lstWMResult != null && lstWMResult.Count > 0 ) {
						foreach ( Repository.WebMethod wm in lstWMResult ) {
							if ( wm.Name == "DoHumanActivity" ) {
								webmeth = wm;
							} else if ( wm.Name == "HumanResponse" ) {
								webmethCallback = wm;
							}
						}
					}
				}
			}
			#endregion

			#region generate Data classes
			///////////////////////////
			if ( logact.HasInputBusinessObject ) {
				deployment.AddBusinessObjectToDataCode(ccuData, this.NamespaceData,
					typeProvider, logact.InputBusinessObject, this.GenerateDataContract);
			}
			if ( logact.HasOutputBusinessObject ) {
				deployment.AddBusinessObjectToDataCode(ccuData, this.NamespaceData,
					typeProvider, logact.OutputBusinessObject, this.GenerateDataContract);
			}
			if ( logwmeth != null ) {
				if ( logwmeth.InputBusinessObject != null && logwmeth.InputBusinessObject.Schema != null ) {
					deployment.AddBusinessObjectToDataCode(ccuData, this.NamespaceData,
						typeProvider, logwmeth.InputBusinessObject, this.GenerateDataContract);
				}
				if ( logwmeth.OutputBusinessObject != null && logwmeth.OutputBusinessObject.Schema != null ) {
					deployment.AddBusinessObjectToDataCode(ccuData, this.NamespaceData,
						typeProvider, logwmeth.OutputBusinessObject, this.GenerateDataContract);
				}
			}
			///////////////////////////
			#endregion generate Data classes

			#region get generated type of input/output business objects
			///////////////////////////
			CodeTypeReference typeRefOutput = null;
			CodeTypeReference typeRefInput = null;
			List<CodeTypeReference> listTypeRefInputLogAct = new List<CodeTypeReference>();
			getGeneratedIOTypesOfLogicalActivity(typeProvider, logact, out typeRefOutput, out typeRefInput);
			getGeneratedIOTypesOfLogicalActivity(typeProvider, logact, out typeRefOutput, ref listTypeRefInputLogAct);
			// add property for output business object to code beside
			if ( typeRefOutput != null && logact.OutputBusinessObject != null ) {
				addPropertyForBObjectToCodeBeside(typeProvider, logact.OutputBusinessObject, typeRefOutput);
			}
			///////////////////////////
			#endregion get generated type of output business object

			#region generate Web Method Contract
			string contractnspace = "Contract";
			System.Web.Services.Description.ServiceDescription wsdl = null;
			Collection<System.ServiceModel.Channels.Binding> bindings = null;
			///////////////////////////
			if ( webmeth != null && websvc != null ) {
				deployment.GenerateWebMethodContract(currentSvcGenType, ref typeProvider,
					ref typeRefLogActContract, websvc,
					ref contractnspace, ref wsdl, ref bindings, logact,
					out endpointConfigName, configuration, ccuContracts);
				if ( string.IsNullOrEmpty(endpointConfigName) ) {
					dicWebServiceIDEPConfigName.TryGetValue(websvc.ID, out endpointConfigName);
				} else if ( !dicWebServiceIDEPConfigName.ContainsKey(websvc.ID) ) {
					dicWebServiceIDEPConfigName.Add(websvc.ID, endpointConfigName);
				}
			} else if ( lstLogRuleResultEPInfos != null && lstLogRuleResultEPInfos.Count > 0 ) {
				foreach ( var item in lstLogRuleResultEPInfos ) {
					webmeth = item.UseProxy ?
						item.RuleResultEndpoint.ProxyWebMethod :
						item.RuleResultEndpoint.WebMethod;
					webmethCallback = item.UseProxy ?
						item.RuleResultEndpoint.ProxyCallbackWebMethod :
						item.RuleResultEndpoint.CallbackWebMethod;
					websvc = item.UseProxy ?
						item.RuleResultEndpoint.ProxyWebService :
						item.RuleResultEndpoint.WebService;
					if ( webmeth != null && websvc != null ) {
						deployment.GenerateWebMethodContract(
							currentSvcGenType, ref typeProvider,
							ref item.TypeRefLogActContract,
							websvc,
							ref item.ContractNamespace, ref item.Wsdl, ref item.Bindings,
							logact, out item.EndpointConfigName, configuration,
							ccuContracts);
						if ( string.IsNullOrEmpty(item.EndpointConfigName) ) {
							dicWebServiceIDEPConfigName.TryGetValue(websvc.ID, out item.EndpointConfigName);
						} else if ( !dicWebServiceIDEPConfigName.ContainsKey(websvc.ID) ) {
							dicWebServiceIDEPConfigName.Add(websvc.ID, item.EndpointConfigName);
						}
					}
				}
				webmeth = null;
				webmethCallback = null;
				websvc = null;
			}
			///////////////////////////
			#endregion generate Web Method Contract

			#region generate Mapping class code
			///////////////////////////
			CodeMemberMethod methInMap = null;
			//CodeMemberMethod methInMapPhys = null;
			CodeMemberMethod methOutMap = null;
			CodeMemberMethod methContract = null;
			CodeTypeReference typeRefMapClass = new CodeTypeReference(
				typeProvider.GetType(this.Namespace + ".Mapping"));
			bool generateConfigLogPhys = this.Workflow.IsConfigurable;
			bool generateConfigSubscribe = this.Workflow.IsConfigurable;
			if ( webmeth != null && websvc != null ) {
				deployment.GenerateMapping(
					ccuContracts, ccuMapping, _ctdMapping, _ctorMapping,
					configuration,
					currentSvcGenType, ref typeProvider, typeRefLogActContract,
					logwmeth.Name, logact, logact.LogicalMethod, null, webmeth, webmethCallback, null, ref methInMap, ref methOutMap,
					ref methContract, typeRefMapClass, typeRefOutput, typeRefInput,
					listTypeRefInputLogAct, useProxy,
					generateConfigLogPhys,
					generateConfigSubscribe);
			} else if ( lstLogRuleResultEPInfos != null && lstLogRuleResultEPInfos.Count > 0 ) {
				foreach ( var item in lstLogRuleResultEPInfos ) {
					webmeth = item.UseProxy ?
						item.RuleResultEndpoint.ProxyWebMethod :
						item.RuleResultEndpoint.WebMethod;
					webmethCallback = item.UseProxy ?
						item.RuleResultEndpoint.ProxyCallbackWebMethod :
						item.RuleResultEndpoint.CallbackWebMethod;
					websvc = item.UseProxy ?
						item.RuleResultEndpoint.ProxyWebService :
						item.RuleResultEndpoint.WebService;
					if ( webmeth != null && websvc != null ) {
						deployment.GenerateMapping(
							ccuContracts, ccuMapping, _ctdMapping, _ctorMapping,
							configuration,
							currentSvcGenType, ref typeProvider, item.TypeRefLogActContract,
							logwmeth.Name + "_" + item.RuleResultEndpoint.EndpointRuleResult,
							logact, logact.LogicalMethod, item.RuleResultEndpoint,
							webmeth, webmethCallback, null,
							ref item.MethodInMap, ref item.MethodOutMap,
							ref item.MethodContract,
							typeRefMapClass, typeRefOutput, typeRefInput,
							listTypeRefInputLogAct,
							( item.RuleResultEndpoint.ProxyWebMethodID > 0 ),
							generateConfigLogPhys,
							generateConfigSubscribe);
					}
				}
				webmeth = null;
				webmethCallback = null;
				websvc = null;
			}
			///////////////////////////
			#endregion generate Mapping class code

			#region generate ServiceCalls class code
			///////////////////////////
			if ( webmeth != null && websvc != null ) {
				deployment.GenerateServiceCalls(
					ccuServices, _ctdServices, ccuContracts, ccuRules, currentSvcGenType,
					typeProvider, typeRefLogActContract, logcap.LogicalActivityName, true,
					webmeth, webmethCallback, websvc, null, null, logact, logcap, contractnspace,
					methInMap, methOutMap, methContract, typeRefMapClass,
					typeRefOutput, typeRefInput, listTypeRefInputLogAct, bindings,
					endpointConfigName, this.NamespaceData, this.NamespaceRules, false);
			} else if ( lstLogRuleResultEPInfos != null && lstLogRuleResultEPInfos.Count > 0 &&
						logwmeth != null ) {
				// add endpoint rule to rule code
				AddRuleToCode(logwmeth.GetEndpointRule());
				foreach ( var item in lstLogRuleResultEPInfos ) {
					webmeth = item.UseProxy ?
						item.RuleResultEndpoint.ProxyWebMethod :
						item.RuleResultEndpoint.WebMethod;
					webmethCallback = item.UseProxy ?
						item.RuleResultEndpoint.ProxyCallbackWebMethod :
						item.RuleResultEndpoint.CallbackWebMethod;
					websvc = item.UseProxy ?
						item.RuleResultEndpoint.ProxyWebService :
						item.RuleResultEndpoint.WebService;
					deployment.GenerateServiceCalls(
						ccuServices, _ctdServices, ccuContracts, ccuRules, currentSvcGenType,
						typeProvider, item.TypeRefLogActContract,
						logcap.LogicalActivityName + "_" + item.RuleResultEndpoint.EndpointRuleResult,
						true, webmeth, webmethCallback, websvc, null, null, logact, logcap,
						item.ContractNamespace, item.MethodInMap, item.MethodOutMap,
						item.MethodContract, typeRefMapClass, typeRefOutput, typeRefInput,
						listTypeRefInputLogAct, item.Bindings, item.EndpointConfigName,
						this.NamespaceData, this.NamespaceRules, false);
				}
				webmeth = null;
				webmethCallback = null;
				websvc = null;
			}
			///////////////////////////
			#endregion generate ServiceCalls class code

			#region generate LogicalActivities class code
			///////////////////////////
			// create logical activity method:
			// public void LOGACTNAME(IKPITrackingActivity activity) {...}

			CodeMemberMethod methodLogAct = new CodeMemberMethod();
			methodLogAct.Name = logcap.LogicalActivityName;
			methodLogAct.Attributes = MemberAttributes.Final | MemberAttributes.Public;
			methodLogAct.Parameters.Add(
				new CodeParameterDeclarationExpression(
					typeof(ActivityExecutionContext), "context"));
			methodLogAct.Parameters.Add(
				new CodeParameterDeclarationExpression(
					typeof(ITrackingActivity), "activity"));
			Type t = typeProvider.GetType(this.Namespace + ".ServiceCalls");
			CodeTypeReference typeRefSvcCalls = new CodeTypeReference(t);

			CodeConditionStatement codeConditionIsSim =
								new CodeConditionStatement();
			methodLogAct.Statements.Add(codeConditionIsSim);

			// if ( (this._orchestration.IsSimulation == true) &&
			//		(this._orchestration.SimulateAllLogicalActivities == true) )
			codeConditionIsSim.Condition =
				new CodeBinaryOperatorExpression(
					new CodeBinaryOperatorExpression(
						new CodePropertyReferenceExpression(
							new CodeFieldReferenceExpression(
								new CodeThisReferenceExpression(),
								"_orchestration"),
							"IsSimulation"),
						CodeBinaryOperatorType.ValueEquality,
						new CodePrimitiveExpression(true)),
					CodeBinaryOperatorType.BooleanAnd,
					new CodeBinaryOperatorExpression(
						new CodePropertyReferenceExpression(
							new CodeFieldReferenceExpression(
								new CodeThisReferenceExpression(),
								"_orchestration"),
							"SimulateAllLogicalActivities"),
						CodeBinaryOperatorType.ValueEquality,
						new CodePrimitiveExpression(true)));
			// add KPIs to tracking data
			BindingListEx<Repository.KPIMetric> lstMetrics = null;
			if ( verb != null ) {
				lstMetrics = verb.GetKPIMetrics();
			}
			if ( lstMetrics != null && lstMetrics.Count > 0 ) {
				codeConditionIsSim.TrueStatements.Add(
					new CodeCommentStatement("add KPIs to tracking data"));
				foreach ( Repository.KPIMetric metric in lstMetrics ) {
					codeConditionIsSim.TrueStatements.Add(
						new CodeMethodInvokeExpression(
							new CodeArgumentReferenceExpression("activity"),
							"AddKPIData",
							new CodePrimitiveExpression(metric.Name),
							new CodePrimitiveExpression(metric.Value),
							new CodePrimitiveExpression(metric.Unit),
							new CodePrimitiveExpression(metric.DataType)));
				}
			}
			RepositoryBusinessRule epRule = null;
			if ( logwmeth != null ) epRule = logwmeth.GetEndpointRule();

			CodeStatementCollection statements = generateLogActServiceCall(
				logcap, logact, null/*op*/, verb, websvc,
				epRule, lstLogRuleResultEPInfos,
				typeRefOutput, typeRefInput,
				typeRefSvcCalls);

			codeConditionIsSim.FalseStatements.AddRange(statements);

			_ctdLogActs.Members.Add(methodLogAct);
			refreshTypeProvider(ref typeProvider, ref ccuLogActivities);
			///////////////////////////
			#endregion generate LogicalActivities class code

			return currentSvcGenType;
		}
		#endregion

		#region Data Aggregator Activity
		private void generateDataAggregatorActivityCode(
			Activity act, IDesignerHost host, RepositoryService repSvc, Deployment deployment,
			ref TypeProvider typeProvider, out bool doContinue)
		{
			DataAggregatorActivity daact = (DataAggregatorActivity)act;
			doContinue = false;

			if ( daact.LogicalActivityId <= 0 ) {
				doContinue = true;
				return;	// EXIT
			}
			if ( daact.ActivitiesClass == null ) {
				IDesigner idesigner = null;
				if ( host != null ) idesigner = (IDesigner)host.GetDesigner(daact);
				ActivityBind actbindIn = new ActivityBind(this.ClassName, "LogicalActivitiesClass");
				daact.SetBinding(DataAggregatorActivity.ActivitiesClassProperty, actbindIn);
				if ( idesigner != null ) idesigner.Initialize(daact);
			}
			LogicalActivity logact = repSvc.GetItem(ItemType.LogicalActivity,
				daact.LogicalActivityId, true) as LogicalActivity;

			if ( logact == null || logact.OutputBusinessObjectID <= 0 ) {
				doContinue = true;
				return;	// EXIT
			}

			BusinessObject boOutput = logact.GetOutputBusinessObject();
			if ( boOutput == null || boOutput.Schema == null ) {
				doContinue = true;
				return;	// EXIT
			}

			#region generate Data classes
			///////////////////////////
			// add output schema classes
			deployment.AddBusinessObjectToDataCode(ccuData, this.NamespaceData,
				typeProvider, boOutput, this.GenerateDataContract);
			///////////////////////////
			#endregion generate Data classes

			#region generate Mapping class code
			///////////////////////////
			CodeMemberMethod methMap = null;
			CodeTypeReference typeRefMapClass =
								new CodeTypeReference(typeProvider.GetType(this.Namespace + ".Mapping"));
			// get mapping
			XsltDocument xslt = null;
			if ( !string.IsNullOrEmpty(logact.LogicalInputXslt) ) {
				xslt = new XsltDocument();
				xslt.LoadXml(logact.LogicalInputXslt);
			} else {
				//continue;
			}

			// get input and output type references
			CodeTypeReference typeRefOutput;
			List<CodeTypeReference> listTypeRefInput = new List<CodeTypeReference>();
			getGeneratedIOTypesOfDataAggregation(typeProvider, boOutput, logact,
				out typeRefOutput, ref listTypeRefInput);

			// add property for output business object to code beside
			if ( typeRefOutput != null && boOutput != null ) {
				addPropertyForBObjectToCodeBeside(typeProvider, boOutput, typeRefOutput);
			}
			///////////////////////////

			// use / is configurable
			bool generateConfigSubscribe = this.Workflow.IsConfigurable;

			// save xslt as constant strings
			CodeMemberField fieldXslt = null;
			if ( xslt != null && xslt.DocumentElement != null ) {
				fieldXslt = new CodeMemberField(typeof(string), "xsltInput" + daact.LogicalActivityName);
				if ( generateConfigSubscribe ) {
					fieldXslt.Attributes = MemberAttributes.Private;
				} else {
					fieldXslt.Attributes = MemberAttributes.Private | MemberAttributes.Const;
				}
				fieldXslt.InitExpression = new CodePrimitiveExpression(xslt.DocumentElement.OuterXml);
			}

			// generate mapping method			
			List<Type> typesWSInput = new List<Type>();
			string contractnspace = "Contract";
			foreach ( string sType in logact.LogicalMethod.WebMethod.InputTypeName.Split(';') ) {
				string type = sType.Trim();
				string ns = null;
				if ( type.Contains(":") ) {
					ns = type;
					string[] splitType = type.Split(':');
					type = splitType[splitType.Length - 1];
					ns = ns.Remove(ns.Length - type.Length - 1, type.Length + 1);
				}
				if ( type.StartsWith("System.") ) {
					typesWSInput.Add(Type.GetType(type));
				} else {
					Type t1 = typeProvider.GetType(type);
					if ( t1 == null ) t1 = typeProvider.GetType(type + "Request");
					if ( t1 == null ) t1 = typeProvider.GetType(contractnspace + "." + type + "Request");
					typesWSInput.Add(t1);
					//if ( !string.IsNullOrEmpty(ns) ) {
					//    dicTypeNamespace.Add(t, ns);
					//}
				}
			}
			methMap = deployment.GenerateMappingMethodForSubscriptions(
				typeProvider, daact.LogicalActivityName, listTypeRefInput,
				typeRefMapClass, fieldXslt, null,
				false,
				generateConfigSubscribe,
				logact.LogicalMethod.ExtendedProperties.InputCodeMapping, typesWSInput, null, typeRefOutput);
			_ctdMapping.Members.Add(fieldXslt);
			_ctdMapping.Members.Add(methMap);

			refreshTypeProvider(ref typeProvider, ref ccuLogActivities);
			///////////////////////////
			#endregion generate Mapping class code

			#region generate LogicalActivities class code
			///////////////////////////
			CodeMemberMethod methodLogAct = new CodeMemberMethod();
			methodLogAct.Name = daact.LogicalActivityName;
			methodLogAct.Attributes = MemberAttributes.Final | MemberAttributes.Public;
			Type t = typeProvider.GetType(this.Namespace + ".Mapping");
			Type typeOutput = typeProvider.GetType(this.Namespace + ".Data." + boOutput.Name);

			CodeExpression mapAggTargetObj =
								( methMap.Attributes & MemberAttributes.Static ) == MemberAttributes.Static ?
				(CodeExpression)new CodeTypeReferenceExpression(typeRefMapClass) :
				(CodeExpression)new CodePropertyReferenceExpression(
					new CodeFieldReferenceExpression(
						new CodeThisReferenceExpression(), Deployment.cOrchestrationField),
					"Mapping");

			CodeMethodInvokeExpression methCallMapping =
								new CodeMethodInvokeExpression(
					new CodeMethodReferenceExpression(
						mapAggTargetObj,
						methMap.Name));

			NamedBusinessObjectCollection subscriptions = logact.GetSubscribedBusinessObjects();
			if ( subscriptions.Count > 0 ) {
				foreach ( NamedBusinessObject item in subscriptions ) {
					methCallMapping.Parameters.Add(
						new CodePropertyReferenceExpression(
							new CodeFieldReferenceExpression(
								new CodeThisReferenceExpression(), Deployment.cOrchestrationField),
								item.Name + Deployment.cBObjPropSuffix));
				}
			}
			if ( typeRefOutput != null ) {
				methodLogAct.Statements.Add(	// OUTPUTTYPE output = null;
					new CodeVariableDeclarationStatement(
						typeOutput,
						"output",
						new CodePrimitiveExpression(null)));
				methodLogAct.Statements.Add(	// XmlDocument xdOutput = methodMapping(input0, input1, ...);
					new CodeVariableDeclarationStatement(
						typeof(XmlDocument),
						"xdOutput",
						methCallMapping));
				methodLogAct.Statements.Add(	// MemoryStream msOutput = new MemoryStream();
					new CodeVariableDeclarationStatement(
						typeof(MemoryStream),
						"msOutput",
						new CodeObjectCreateExpression(typeof(MemoryStream))));
				methodLogAct.Statements.Add( // xdOutput.Save(msOutput);
					new CodeMethodInvokeExpression(
						new CodeVariableReferenceExpression("xdOutput"),
						"Save",
						new CodeVariableReferenceExpression("msOutput")));
				methodLogAct.Statements.Add(	// msOutput.Position = 0;
					new CodeAssignStatement(
						new CodePropertyReferenceExpression(
							new CodeVariableReferenceExpression("msOutput"),
							"Position"),
						new CodePrimitiveExpression(0)));
				methodLogAct.Statements.Add(	// object obj = null;
					new CodeVariableDeclarationStatement(
						typeof(object),
						"obj",
						new CodePrimitiveExpression(null)));
				// use XmlSerialzer
				// XmlRootAttribute root = new XmlRootAttribute(TYPENAME);
				methodLogAct.Statements.Add(
					new CodeVariableDeclarationStatement(
						typeof(XmlRootAttribute),
						"root",
						new CodeObjectCreateExpression(
							typeof(XmlRootAttribute),
							new CodePrimitiveExpression(boOutput.Name))));
				// root.Namespace = xdOuput.DocumentElement.NamespaceURI;
				methodLogAct.Statements.Add(
					new CodeAssignStatement(
						new CodePropertyReferenceExpression(
							new CodeVariableReferenceExpression("root"),
							"Namespace"),
						new CodePropertyReferenceExpression(
							new CodePropertyReferenceExpression(
								new CodeVariableReferenceExpression("xdOutput"),
								"DocumentElement"),
							"NamespaceURI")));
				object[] attibs = typeOutput.GetCustomAttributes(typeof(DataContractAttribute), false);
				if ( attibs == null || attibs.Length == 0 ) {
					// XmlSerializer xsOutput = new XmlSerializer(typeof(OUTPUTTYPE), root);
					methodLogAct.Statements.Add(
						new CodeVariableDeclarationStatement(
							typeof(XmlSerializer),
							"xsOutput",
							new CodeObjectCreateExpression(
								typeof(XmlSerializer),
								new CodeTypeOfExpression(typeOutput),
								new CodeVariableReferenceExpression("root"))));
					methodLogAct.Statements.Add(	// obj = xsOutput.Deserialize(msOutput);
						new CodeAssignStatement(
							new CodeVariableReferenceExpression("obj"),
							new CodeMethodInvokeExpression(
								new CodeVariableReferenceExpression("xsOutput"),
								"Deserialize",
								new CodeVariableReferenceExpression("msOutput"))));
				} else {
					// DataContractSerializer xs = new DataContractSerializer(typeof(OUTPUTTYPE), root.Name, root.Namespace);
					methodLogAct.Statements.Add(
						new CodeVariableDeclarationStatement(
							typeof(DataContractSerializer),
							"xsOutput",
							new CodeObjectCreateExpression(
								typeof(DataContractSerializer),
								new CodeTypeOfExpression(typeOutput),
								new CodePropertyReferenceExpression(
									new CodeVariableReferenceExpression("root"), "ElementName"),
								new CodePropertyReferenceExpression(
									new CodeVariableReferenceExpression("root"), "Namespace"))));
					methodLogAct.Statements.Add(	// obj = xsOutput.ReadObject(msOutput);
						new CodeAssignStatement(
							new CodeVariableReferenceExpression("obj"),
							new CodeMethodInvokeExpression(
								new CodeVariableReferenceExpression("xsOutput"),
								"ReadObject",
								new CodeVariableReferenceExpression("msOutput"))));
				}
				methodLogAct.Statements.Add(	// if ( obj.GetType() == OUTPUTTYPE )
					new CodeConditionStatement(
						new CodeBinaryOperatorExpression(
							new CodeMethodInvokeExpression(
								new CodeVariableReferenceExpression("obj"),
								"GetType"),
							CodeBinaryOperatorType.ValueEquality,
							new CodeTypeOfExpression(typeOutput)),
						new CodeStatement[] {
										new CodeAssignStatement(	// output = (OUTPUTTYPE)obj;
											new CodeVariableReferenceExpression("output"),
											new CodeCastExpression(
												typeOutput,
												new CodeVariableReferenceExpression("obj"))),
									},
						new CodeStatement[] {	// else
										new CodeAssignStatement(	// output = null;
											new CodeVariableReferenceExpression("output"),
											new CodePrimitiveExpression(null))
									}));
				methodLogAct.Statements.Add(	// msOutput.Close();
					new CodeMethodInvokeExpression(
						new CodeVariableReferenceExpression("msOutput"),
						"Close"));
				methodLogAct.Statements.Add(	// _orchestration.BOBJECT = output;
					new CodeAssignStatement(
						new CodePropertyReferenceExpression(
							new CodeFieldReferenceExpression(
								new CodeThisReferenceExpression(), Deployment.cOrchestrationField),
								boOutput.Name + Deployment.cBObjPropSuffix),
						new CodeVariableReferenceExpression("output")));
			}
			_ctdLogActs.Members.Add(methodLogAct);
			refreshTypeProvider(ref typeProvider, ref ccuLogActivities);
			///////////////////////////
			#endregion generate LogicalActivities class code
		}
		#endregion

		#region Rule Evaluator Activity
		private void generateRuleEvaluatorActivity(
			Activity act, IDesignerHost host, RepositoryService repSvc, Deployment deployment,
			ref TypeProvider typeProvider, out bool doContinue)
		{
			doContinue = false;

			RuleEvaluatorActivity rea = (RuleEvaluatorActivity)act;
			if ( rea.LogicalActivityId <= 0 ) {
				doContinue = true;
				return; // EXIT
			}
			if ( rea.ActivitiesClass == null ) {
				IDesigner idesigner = null;
				if ( host != null ) idesigner = (IDesigner)host.GetDesigner(rea);
				ActivityBind actbindIn = new ActivityBind(this.ClassName, "LogicalActivitiesClass");
				rea.SetBinding(RuleEvaluatorActivity.ActivitiesClassProperty, actbindIn);
				if ( idesigner != null ) idesigner.Initialize(rea);
			}

			LogicalActivity logact = repSvc.GetItem(ItemType.LogicalActivity,
				rea.LogicalActivityId, true) as LogicalActivity;

			if ( logact == null || logact.OutputBusinessObjectID <= 0 ) {
				doContinue = true;
				return; // EXIT
			}
			BusinessObject boOutput = logact.GetOutputBusinessObject();
			Repository.RepositoryBusinessRule brule = logact.GetBusinessRule();
			if ( boOutput == null || boOutput.Schema == null || brule == null ||
				 string.IsNullOrEmpty(logact.ExtendedProperties.BusinessRuleOutputPath) ) {
				doContinue = true;
				return; // EXIT
			}
			#region create output data code and property
			deployment.AddBusinessObjectToDataCode(ccuData, this.NamespaceData,
				typeProvider, boOutput, this.GenerateDataContract);

			Type typeBOOut = typeProvider.GetType(
				this.NamespaceData + "." + boOutput.Name);
			if ( typeBOOut == null )
				throw new InvalidOperationException("The output business object \"" + boOutput.Name + "\" does not exists in the current process.");

			CodeTypeReference typeRefOutput = new CodeTypeReference(typeBOOut);
			if ( typeRefOutput == null )
				throw new InvalidOperationException("The output business object \"" + boOutput.Name + "\" does not exists in the current process.");

			if ( typeRefOutput != null ) {
				addPropertyForBObjectToCodeBeside(typeProvider, boOutput, typeRefOutput);
			}
			#endregion

			#region generate LogicalActivities class code
			///////////////////////////
			CodeMemberMethod methodLogAct = new CodeMemberMethod();
			methodLogAct.Name = rea.LogicalActivityName;
			methodLogAct.Attributes = MemberAttributes.Final | MemberAttributes.Public;

			// string result = Rules.RULE_NAME(_orchestration.PARAM_1[,...]);
			List<CodeExpression> lstRuleParams = new List<CodeExpression>();
			foreach ( string paramname in brule.GetParameters().Keys ) {
				lstRuleParams.Add(
					new CodePropertyReferenceExpression(
						new CodeFieldReferenceExpression(
							new CodeThisReferenceExpression(),
							"_orchestration"),
						paramname));
			}
			string rulesclass = this.NamespaceRules + ".Rules";
			CodeMemberMethod methodRule = Helpers.GetMember<CodeMemberMethod>(
				ccuRules, rulesclass, brule.Name);
			if ( methodRule == null ) {
				throw new NullReferenceException(
					string.Format("The rule \"{0}\" was not generated correctly.", brule.Name));
			}
			CodeExpression rulesTargetObj =
								( methodRule.Attributes & MemberAttributes.Static ) == MemberAttributes.Static ?
				(CodeExpression)new CodeTypeReferenceExpression(this.NamespaceRules + ".Rules") :
				(CodeExpression)new CodePropertyReferenceExpression(
					new CodeFieldReferenceExpression(
						new CodeThisReferenceExpression(), Deployment.cOrchestrationField),
					"Rules");
			CodeMethodInvokeExpression methinvoke = new CodeMethodInvokeExpression(
				rulesTargetObj,
				brule.Name,
				lstRuleParams.ToArray());
			methodLogAct.Statements.Add(
				new CodeVariableDeclarationStatement(
					typeof(string),
					"result",
					methinvoke));

			string[] resultPath = logact.ExtendedProperties.BusinessRuleOutputPath.Split('.');
			if ( resultPath.Length <= 1 ) {
				throw new Exception(string.Format(
					"Invalid result path selected.{0}{0}Please select a field of an business object in the Rule Evaluator configuration dialog.",
					Environment.NewLine));
			}
			if ( resultPath.Length > 2 ) {
				throw new Exception(
					"In this version it is not possible to select " +
					"a field from child business objects.");
			}
			// foreach
			CodeExpression expPath = new CodeFieldReferenceExpression(
				new CodeThisReferenceExpression(),
				"_orchestration");
			for ( int i = 0; i < resultPath.Length - 1; i++ ) {
				// if ( _orchestration.RESULT_OBJECT == null )
				// _orchestration.RESULT_OBJECT = new RESULT_OBJECT_TYPE();
				expPath = new CodePropertyReferenceExpression(
					expPath,
					resultPath[i]);
				CodeConditionStatement cond = new CodeConditionStatement(
					new CodeBinaryOperatorExpression(
						expPath,
						CodeBinaryOperatorType.ValueEquality,
						new CodePrimitiveExpression(null)),
					new CodeAssignStatement(
						expPath,
						new CodeObjectCreateExpression(typeRefOutput)));

				methodLogAct.Statements.Add(cond);
			}
			expPath = new CodePropertyReferenceExpression(
				expPath,
				resultPath[resultPath.Length - 1]);
			// _orchestration.RESULT_OBJECT.RESULT_FIELD = result;
			methodLogAct.Statements.Add(
				new CodeAssignStatement(
					expPath,
					new CodeVariableReferenceExpression("result")));

			_ctdLogActs.Members.Add(methodLogAct);
			refreshTypeProvider(ref typeProvider, ref ccuLogActivities);
			#endregion
		}
		#endregion

		#region Notification Activity
		private void createNotificationActivity(Activity act, IDesignerHost host, RepositoryService repSvc)
		{
			NotificationActivity notifcation = (NotificationActivity)act;
			LogicalActivity logact = repSvc.GetItem<LogicalActivity>(notifcation.LogicalActivityId);
			if ( logact == null ) {
				throw new Exception(
					string.Format("Please configurate the notification activity \"{0}\".",
					notifcation.Text.Replace(Environment.NewLine, "").Replace("\t", "")));
			}
			IDesigner idesigner = null;
			if ( host != null ) idesigner = (IDesigner)host.GetDesigner(notifcation);

			notifcation.ParameterBindings.Clear();
			foreach ( var bobj in logact.GetSubscribedBusinessObjects() ) {
				WorkflowParameterBinding wpb = new WorkflowParameterBinding();
				wpb.ParameterName = bobj.Name;
				wpb.SetBinding(
					WorkflowParameterBinding.ValueProperty,
					new ActivityBind(this.ClassName, bobj.Name));
				notifcation.ParameterBindings.Add(wpb);
			}
			if ( notifcation.ActivitiesClass == null ) {
				ActivityBind actbindIn = new ActivityBind(this.ClassName, "LogicalActivitiesClass");
				notifcation.SetBinding(NotificationActivity.ActivitiesClassProperty, actbindIn);
			}
			if ( idesigner != null ) idesigner.Initialize(notifcation);

			string hostName = string.Format(NotificationActivity.HostKey, act.Name);
			string sender = string.Format(NotificationActivity.SenderKey, act.Name);
			string userName = string.Format(NotificationActivity.UserNameKey, act.Name);
			string password = string.Format(NotificationActivity.PasswordKey, act.Name);
			string smtpport = string.Format(NotificationActivity.SmtpPortKey, act.Name);
			string usessl = string.Format(NotificationActivity.UseSSLKey, act.Name);
			string recipient = string.Format(NotificationActivity.RecipientKey, act.Name);
			string subject = string.Format(NotificationActivity.SubjectKey, act.Name);
			string message = string.Format(NotificationActivity.MessageKey, act.Name);
			KeyValueConfigurationElement kvceHost =
								new KeyValueConfigurationElement(hostName, notifcation.NotificationHost);
			KeyValueConfigurationElement kvceSender =
								new KeyValueConfigurationElement(sender, notifcation.NotificationSender);
			KeyValueConfigurationElement kvceUser =
								new KeyValueConfigurationElement(userName, notifcation.NotificationUserName);
			KeyValueConfigurationElement kvcePassword =
								new KeyValueConfigurationElement(password, notifcation.NotificationPassword);
			KeyValueConfigurationElement kvceSmtpPort =
								new KeyValueConfigurationElement(smtpport, notifcation.NotificationSmtpPort.ToString());
			KeyValueConfigurationElement kvceUseSSL =
								new KeyValueConfigurationElement(usessl, notifcation.NotificationUseSSL.ToString());
			KeyValueConfigurationElement kvceRecipient =
									new KeyValueConfigurationElement(recipient, notifcation.Notification == null ? null : notifcation.Notification.Recipient);
			KeyValueConfigurationElement kvceSubject =
									new KeyValueConfigurationElement(subject, notifcation.Notification == null ? null : notifcation.Notification.Subject);
			KeyValueConfigurationElement kvceMessage =
									new KeyValueConfigurationElement(message, notifcation.Notification == null ? null : notifcation.Notification.Message);
			configuration.AppSettings.Settings.Add(kvceHost);
			configuration.AppSettings.Settings.Add(kvceSender);
			configuration.AppSettings.Settings.Add(kvceUser);
			configuration.AppSettings.Settings.Add(kvcePassword);
			configuration.AppSettings.Settings.Add(kvceSmtpPort);
			configuration.AppSettings.Settings.Add(kvceUseSSL);
			configuration.AppSettings.Settings.Add(kvceRecipient);
			configuration.AppSettings.Settings.Add(kvceSubject);
			configuration.AppSettings.Settings.Add(kvceMessage);
		}
		#endregion

		#region Extended Code Activity
		private void createExtendedCodeActivity(Activity act, IDesignerHost host)
		{
			ExtendedCodeActivity codeAct = (ExtendedCodeActivity)act;
			IDesigner idesigner = null;
			if ( host != null ) idesigner = (IDesigner)host.GetDesigner(codeAct);

			if ( codeAct.ActivitiesClass == null ) {
				ActivityBind actbindIn = new ActivityBind(this.ClassName, "LogicalActivitiesClass");
				codeAct.SetBinding(ExtendedCodeActivity.ActivitiesClassProperty, actbindIn);
				if ( idesigner != null ) idesigner.Initialize(codeAct);
			}
		}
		#endregion

		#region Workflow Interface
		private void initLogicalMethodCallActivity(IDesignerHost host, RepositoryService repSvc, TypeProvider typeProvider, Activity act)
		{
			LogicalMethodCallActivity lma = (LogicalMethodCallActivity)act;
			LogicalActivity la = repSvc.GetItem<LogicalActivity>(lma.LogicalActivityId);
			if ( la == null && lma.LogicalActivityId > 0 ) {
				throw new Exception(string.Format("Unknown Error. Please recreate the activity '{0}' in the composite activity '{1}'.", act.Name, act.Parent.Name));
			}
			WorkflowMethod wm = repSvc.GetItem<WorkflowMethod>(la.WorkflowMethodID);
			if ( la != null && wm != null ) {
				IDesigner idesigner = null;
				if ( host != null ) idesigner = (IDesigner)host.GetDesigner(lma);
				Helpers.SetActivityProperty(lma, "InterfaceType",
					typeProvider.GetType(this.Namespace + "." + _ctdLocalInterface.Name));
				Helpers.SetActivityProperty(lma, "MethodName", lma.LogicalActivityName);
				lma.ParameterBindings.Clear();
				WorkflowParameterBinding wpb;
				// add workflow instance parameter
				wpb = new WorkflowParameterBinding();
				wpb.ParameterName = Deployment.cWorkflowInstanceId;
				wpb.SetBinding(WorkflowParameterBinding.ValueProperty,
					new ActivityBind(this.ClassName, PropertyNames.WorkflowInstanceId));
				lma.ParameterBindings.Add(wpb);
				if ( wm.InputBusinessObjectID > 0 ) {
					// add process output parameter
					wpb = new WorkflowParameterBinding();
					wpb.ParameterName = Deployment.cMethodInput;
					wpb.SetBinding(WorkflowParameterBinding.ValueProperty,
						new ActivityBind(this.ClassName, wm.InputBusinessObjectName));
					lma.ParameterBindings.Add(wpb);
				}
				if ( wm.OutputBusinessObjectID > 0 ) {
					// add return value parameter
					wpb = new WorkflowParameterBinding();
					wpb.ParameterName = "(ReturnValue)";
					wpb.SetBinding(WorkflowParameterBinding.ValueProperty,
						new ActivityBind(this.ClassName, wm.OutputBusinessObjectName));
					lma.ParameterBindings.Add(wpb);
				}
				if ( idesigner != null ) idesigner.Initialize(lma);
			}
		}

		private void initLogicalInputActivity(IDesignerHost host, RepositoryService repSvc, TypeProvider typeProvider, Activity act)
		{
			LogicalInputActivity lia = (LogicalInputActivity)act;
			LogicalActivity la = repSvc.GetItem<LogicalActivity>(lia.LogicalActivityId);
			if ( lia is IncomingEvent && la == null ) {
				return;
			}
			if ( la == null && lia.LogicalActivityId > 0 ) {
				throw new Exception(string.Format("Unknown Error. Please recreate the activity '{0}' in the composite activity '{1}'.", act.Name, act.Parent.Name));
			}
			WorkflowEvent we = repSvc.GetItem<WorkflowEvent>(la.WorkflowEventID);
			if ( la != null && we != null ) {
				IDesigner idesigner = null;
				if ( host != null ) idesigner = (IDesigner)host.GetDesigner(lia);
				Helpers.SetActivityProperty(lia, "InterfaceType",
					typeProvider.GetType(this.Namespace + "." + _ctdLocalInterface.Name));
				Helpers.SetActivityProperty(lia, "EventName", lia.LogicalActivityName);
				lia.ParameterBindings.Clear();
				WorkflowParameterBinding wpb;
				if ( we.BusinessObjectID > 0 ) {
					// add workflow instance parameter
					wpb = new WorkflowParameterBinding();
					wpb.ParameterName = "e";
					wpb.SetBinding(WorkflowParameterBinding.ValueProperty,
						new ActivityBind(this.ClassName, la.InputVariableName + Deployment.cExternalDataEventArgs));
					lia.ParameterBindings.Add(wpb);
				}
				if ( idesigner != null ) idesigner.Initialize(lia);
			}
		}
		#endregion

		#region Generate IO Types

		private void getGeneratedIOTypesOfOperation(TypeProvider typeProvider,
			Repository.Operation op, out CodeTypeReference typeRefOutput, out CodeTypeReference typeRefInput)
		{
			typeRefOutput = null;
			typeRefInput = null;

			if ( op.OutputSchema != null && !string.IsNullOrEmpty(op.OutputBusinessObjectName) ) {
				Type t = typeProvider.GetType(this.NamespaceData + "." + op.OutputBusinessObjectName);
				if ( t == null )
					throw new InvalidOperationException("The output business object \"" + op.OutputBusinessObjectName + "\" does not exists in the current process.");

				typeRefOutput = new CodeTypeReference(t);
				if ( typeRefOutput == null )
					throw new InvalidOperationException("The output business object \"" + op.OutputBusinessObjectName + "\" does not exists in the current process.");
			}
			if ( op.InputSchema != null && !string.IsNullOrEmpty(op.InputBusinessObjectName) ) {
				Type t = typeProvider.GetType(this.NamespaceData + "." + op.InputBusinessObjectName);
				if ( t == null )
					throw new InvalidOperationException("The input business object \"" + op.InputBusinessObjectName + "\" does not exists in the current process.");

				typeRefInput = new CodeTypeReference(t);
				if ( typeRefInput == null )
					throw new InvalidOperationException("The input business object \"" + op.InputBusinessObjectName + "\" does not exists in the current process.");
			}

		}
		private void getGeneratedIOTypesOfLogicalActivity(TypeProvider typeProvider,
			Repository.LogicalActivity logact, out CodeTypeReference typeRefOutput, out CodeTypeReference typeRefInput)
		{
			typeRefOutput = null;
			typeRefInput = null;

			if ( logact.HasOutputBusinessObject ) {
				string outboname = logact.OutputBusinessObject.Name;
				Type t = typeProvider.GetType(this.NamespaceData + "." + outboname);
				if ( t == null )
					throw new InvalidOperationException("The output business object \"" + outboname +
														"\" does not exists in the current process.");

				typeRefOutput = new CodeTypeReference(t);
				if ( typeRefOutput == null )
					throw new InvalidOperationException("The output business object \"" + outboname +
														"\" does not exists in the current process.");
			}
			if ( logact.HasInputBusinessObject ) {
				string inboname = logact.InputBusinessObject.Name;
				Type t = typeProvider.GetType(this.NamespaceData + "." + inboname);
				if ( t == null )
					throw new InvalidOperationException("The input business object \"" + inboname +
														"\" does not exists in the current process.");

				typeRefInput = new CodeTypeReference(t);
				if ( typeRefInput == null )
					throw new InvalidOperationException("The input business object \"" + inboname +
														"\" does not exists in the current process.");
			}

		}
		private void getGeneratedIOTypesOfLogicalActivity(TypeProvider typeProvider,
			OpenComposite.EII.Repository.LogicalActivity logact,
			out CodeTypeReference typeRefOutput, ref List<CodeTypeReference> listTypeRefInputLogAct)
		{
			typeRefOutput = null;

			if ( logact.HasOutputBusinessObject ) {
				Type t = typeProvider.GetType(this.NamespaceData + "." + logact.OutputBusinessObject.Name);
				if ( t == null )
					throw new InvalidOperationException("The Business Object \"" + logact.OutputBusinessObject.Name + "\" does not exists in the current process.");
				typeRefOutput = new CodeTypeReference(t);
			}
			NamedBusinessObjectCollection bos = logact.GetSubscribedBusinessObjects();
			if ( bos != null ) {
				foreach ( NamedBusinessObject item in bos ) {
					Type t = null;
					if ( item.BusinessObject.WorkflowFieldID > 0 ) {
						if ( item.BusinessObject.WorkflowField.BusinessObjectID > 0 ) {
							t = typeProvider.GetType(this.NamespaceData + "." + item.BusinessObject.WorkflowField.BusinessObject.Name);
						} else {
							t = Global.Data.GetDOTNETTypeofXSDDataType(item.BusinessObject.WorkflowField.DataType);
						}
					} else {
						t = typeProvider.GetType(this.NamespaceData + "." + item.BusinessObject.Name);
					}
					if ( t != null ) {
						CodeTypeReference ctr = new CodeTypeReference(t);
						ctr.UserData.Add("BusinessObject", item);
						listTypeRefInputLogAct.Add(ctr);
					}
				}
			}
		}
		private void getGeneratedIOTypesOfOperation(TypeProvider typeProvider,
			Repository.Verb verb, out CodeTypeReference typeRefOutput, out CodeTypeReference typeRefInput)
		{
			typeRefOutput = null;
			typeRefInput = null;

			if ( verb.OutputBusinessObjectID > 0 && !string.IsNullOrEmpty(verb.OutputBusinessObjectName) ) {
				Type t = typeProvider.GetType(this.NamespaceData + "." + verb.OutputBusinessObjectName);
				if ( t == null )
					throw new InvalidOperationException("The output business object \"" + verb.OutputBusinessObjectName + "\" does not exists in the current process.");

				typeRefOutput = new CodeTypeReference(
					typeProvider.GetType(this.NamespaceData + "." + verb.OutputBusinessObjectName));
				//typeRefOutput = importer.GetCodeTypeReference(
				//    new XmlQualifiedName(op.OutputBusinessObjectName, op.OutputSchema.TargetNamespace));
				if ( typeRefOutput == null )
					throw new InvalidOperationException("The output business object \"" + verb.OutputBusinessObjectName + "\" does not exists in the current process.");
			}
			if ( verb.InputBusinessObjectID > 0 && !string.IsNullOrEmpty(verb.InputBusinessObjectName) ) {
				Type t = typeProvider.GetType(this.NamespaceData + "." + verb.InputBusinessObjectName);
				if ( t == null )
					throw new InvalidOperationException("The input business object \"" + verb.InputBusinessObjectName + "\" does not exists in the current process.");

				typeRefInput = new CodeTypeReference(
					typeProvider.GetType(this.NamespaceData + "." + verb.InputBusinessObjectName));
				//typeRefInput = importer.GetCodeTypeReference(
				//    new XmlQualifiedName(op.InputBusinessObjectName, op.InputSchema.TargetNamespace));
				if ( typeRefInput == null )
					throw new InvalidOperationException("The input business object \"" + verb.InputBusinessObjectName + "\" does not exists in the current process.");
			}

		}
		private void getGeneratedIOTypesOfWorkflow(TypeProvider typeProvider,
			Repository.Workflow wf, out CodeTypeReference typeRefOutput, out CodeTypeReference typeRefInput)
		{
			typeRefOutput = null;
			typeRefInput = null;

			if ( wf.OutputBusinessObjectID > 0 && !string.IsNullOrEmpty(wf.OutputBusinessObject.Name) ) {
				Type t = typeProvider.GetType(this.NamespaceData + "." + wf.OutputBusinessObject.Name);
				if ( t == null )
					throw new InvalidOperationException("The output business object \"" + wf.OutputBusinessObject.Name + "\" does not exists in the current process.");

				typeRefOutput = new CodeTypeReference(
					typeProvider.GetType(this.NamespaceData + "." + wf.OutputBusinessObject.Name));
				//typeRefOutput = importer.GetCodeTypeReference(
				//    new XmlQualifiedName(op.OutputBusinessObjectName, op.OutputSchema.TargetNamespace));
				if ( typeRefOutput == null )
					throw new InvalidOperationException("The output business object \"" + wf.OutputBusinessObject.Name + "\" does not exists in the current process.");
			}
			if ( wf.InputBusinessObjectID > 0 && !string.IsNullOrEmpty(wf.InputBusinessObject.Name) ) {
				Type t = typeProvider.GetType(this.NamespaceData + "." + wf.InputBusinessObject.Name);
				if ( t == null )
					throw new InvalidOperationException("The input business object \"" + wf.InputBusinessObject.Name + "\" does not exists in the current process.");

				typeRefInput = new CodeTypeReference(
					typeProvider.GetType(this.NamespaceData + "." + wf.InputBusinessObject.Name));
				//typeRefInput = importer.GetCodeTypeReference(
				//    new XmlQualifiedName(op.InputBusinessObjectName, op.InputSchema.TargetNamespace));
				if ( typeRefInput == null )
					throw new InvalidOperationException("The input business object \"" + wf.InputBusinessObject.Name + "\" does not exists in the current process.");
			}

		}
		private void getGeneratedIOTypesOfOperation(TypeProvider typeProvider,
			OpenComposite.EII.Repository.Operation op, Repository.BusinessObject[] subscribedBOs,
			out CodeTypeReference typeRefOutput, ref List<CodeTypeReference> listTypeRefInputLogAct)
		{
			typeRefOutput = null;

			if ( op.OutputSchema != null && !string.IsNullOrEmpty(op.OutputBusinessObjectName) ) {
				Type t = typeProvider.GetType(this.NamespaceData + "." + op.OutputBusinessObjectName);
				if ( t == null )
					throw new InvalidOperationException("The Business Object \"" + op.OutputBusinessObjectName + "\" does not exists in the current process.");
				typeRefOutput = new CodeTypeReference(t);
			}
			foreach ( Repository.BusinessObject bo in subscribedBOs ) {
				Type t = typeProvider.GetType(this.NamespaceData + "." + bo.Name);
				if ( t != null ) {
					listTypeRefInputLogAct.Add(new CodeTypeReference(t));
					//throw new InvalidOperationException("The Business Object \"" + bo.Name + "\" does not exists in the current process.");
				}
			}
		}
		private void agetGeneratedIOTypesOfOperation(TypeProvider typeProvider,
			OpenComposite.EII.Repository.Verb verb, Repository.BusinessObject[] subscribedBOs,
			out CodeTypeReference typeRefOutput, ref List<CodeTypeReference> listTypeRefInputLogAct)
		{
			typeRefOutput = null;

			if ( verb.OutputBusinessObjectID > 0 && !string.IsNullOrEmpty(verb.OutputBusinessObjectName) ) {
				Type t = typeProvider.GetType(this.NamespaceData + "." + verb.OutputBusinessObjectName);
				if ( t == null )
					throw new InvalidOperationException("The Business Object \"" + verb.OutputBusinessObjectName + "\" does not exists in the current process.");
				typeRefOutput = new CodeTypeReference(t);
				if ( typeRefOutput == null )
					throw new InvalidOperationException("The Business Object \"" + verb.OutputBusinessObjectName + "\" does not exists in the current process.");
			}
			foreach ( Repository.BusinessObject bo in subscribedBOs ) {
				Type t = typeProvider.GetType(this.NamespaceData + "." + bo.Name);
				if ( t != null ) {
					listTypeRefInputLogAct.Add(new CodeTypeReference(t));
					//throw new InvalidOperationException("The Business Object \"" + bo.Name + "\" does not exists in the current process.");
				}
			}
		}

		private void getGeneratedIOTypesOfDataAggregation(TypeProvider typeProvider,
			OpenComposite.EII.Repository.BusinessObject boOutput, Repository.LogicalActivity logact,
			out CodeTypeReference typeRefOutput, ref List<CodeTypeReference> listTypeRefInput)
		{
			typeRefOutput = null;

			if ( boOutput.Schema != null && !string.IsNullOrEmpty(boOutput.Name) ) {
				typeRefOutput = new CodeTypeReference(
					typeProvider.GetType(this.NamespaceData + "." + boOutput.Name));
				if ( typeRefOutput == null )
					throw new Exception("Unknown Output TypeReference.");
			}
			RepositoryService repSvc = (RepositoryService)this.GetService(typeof(RepositoryService));
			if ( repSvc == null )
				throw new NullReferenceException("RepositoryService not available.");
			NamedBusinessObjectCollection subscribedBOs = logact.GetSubscribedBusinessObjects();
			foreach ( NamedBusinessObject item in subscribedBOs ) {
				Type type = null;
				if ( item.BusinessObject.WorkflowFieldID > 0 ) {
					if ( item.BusinessObject.WorkflowField.BusinessObjectID > 0 ) {
						type = typeProvider.GetType(this.NamespaceData + "." + item.BusinessObject.WorkflowField.BusinessObject.Name);
					} else {
						type = Global.Data.GetDOTNETTypeofXSDDataType(item.BusinessObject.WorkflowField.DataType);
					}
				} else {
					type = typeProvider.GetType(this.NamespaceData + "." + item.BusinessObject.Name);
				}
				if ( type == null ) {
					throw new Exception(
						string.Format("The Business Object '{0}' is not available for the Activity '{1}'.",
							item.BusinessObject.Name, logact.Name));
				}
				CodeTypeReference ctr = new CodeTypeReference(type);
				ctr.UserData.Add("BusinessObject", item);
				listTypeRefInput.Add(ctr);
			}
		}

		#endregion

		#region Logical Activities Service Calls
		private CodeStatementCollection generateLogActServiceCall(
			LogicalCapabilityActivity logcap, Repository.LogicalActivity logact, Repository.Operation op,
			Repository.Verb verb, Repository.WebService websvc,
			RepositoryBusinessRule endpointRule,
			List<LogicalRuleResultEPInfos> logRuleResultEPInfos,
			CodeTypeReference typeRefOutput, CodeTypeReference typeRefInput,
			CodeTypeReference typeRefSvcCalls)
		{
			CodeStatementCollection statements = new CodeStatementCollection();
			if ( logRuleResultEPInfos != null && logRuleResultEPInfos.Count > 0 ) {
				// create service call for endpoint rule result:
				// ServiceCalls sc = new ServiceCalls(this._orchestration);
				// string result = OpenComposite.Orchestration.Rules.ENDPOINTRULE(_orchestration.VAR1, ...);
				// if ( result == "RESULT1" ) {
				//     [this._orchestration.OUTPUT1 = ]sc.InvokeABC_RESULT1([this._orchestration.INPUT1]);
				// } else if ( result == "RESULT2" ) {
				//     [this._orchestration.OUTPUT2 = ]sc.InvokeABC_RESULT2([this._orchestration.INPUT2]);
				// ...
				// } else if ( result = "RESULTn" ) {
				//     [this._orchestration.OUTPUTn = ]sc.InvokeABC_RESULTn([this._orchestration.INPUTn]);
				// }
				// create new ServiceCalls instance
				statements.Add(
					new CodeVariableDeclarationStatement(
						typeRefSvcCalls, "sc",
						new CodeObjectCreateExpression(
							typeRefSvcCalls,
							new CodeFieldReferenceExpression(
								new CodeThisReferenceExpression(),
								"_orchestration"))));
				// evaluate rule
				// string result = Rules.RULE_NAME(_orchestration.PARAM_1[,...]);
				List<CodeExpression> lstRuleParams = new List<CodeExpression>();
				foreach ( string paramname in endpointRule.GetParameters().Keys ) {
					lstRuleParams.Add(
						new CodePropertyReferenceExpression(
							new CodeFieldReferenceExpression(
								new CodeThisReferenceExpression(),
								"_orchestration"),
							paramname));
				}
				CodeExpression rulesTargetObj =
					this.Workflow.IsConfigurable ?
					(CodeExpression)new CodePropertyReferenceExpression(
						new CodeFieldReferenceExpression(
							new CodeThisReferenceExpression(), Deployment.cOrchestrationField),
						"Rules") :
					(CodeExpression)new CodeTypeReferenceExpression(this.NamespaceRules + ".Rules");
				CodeMethodInvokeExpression methinvoke = new CodeMethodInvokeExpression(
					rulesTargetObj,
					endpointRule.Name,
					lstRuleParams.ToArray());
				statements.Add(
					new CodeVariableDeclarationStatement(
						typeof(string), "result", methinvoke));
				CodeConditionStatement currentCondition = null;
				CodeConditionStatement firstCondition = null;
				CodeConditionStatement parentCondition = null;
				for ( int i = 0; i < logRuleResultEPInfos.Count; i++ ) {
					LogicalRuleResultEPInfos epinfos = logRuleResultEPInfos[i];
					currentCondition = new CodeConditionStatement();
					if ( firstCondition == null ) firstCondition = currentCondition;
					currentCondition.Condition =
						new CodeBinaryOperatorExpression(
							new CodeVariableReferenceExpression("result"),
							CodeBinaryOperatorType.IdentityEquality,
							new CodePrimitiveExpression(epinfos.RuleResultEndpoint.EndpointRuleResult));
					// create method invokation
					generateLogActServiceCallInvoke(
						Deployment.cServiceCallPrefix + logcap.LogicalActivityName +
							"_" + epinfos.RuleResultEndpoint.EndpointRuleResult,
						logcap, logact, op, verb,
						typeRefOutput, typeRefInput, currentCondition.TrueStatements);
					if ( parentCondition != null ) {
						parentCondition.FalseStatements.Add(currentCondition);
					}
					parentCondition = currentCondition;
				}
				if ( firstCondition != null ) statements.Add(firstCondition);
			} else if ( websvc != null ) {
				// create service call for single web service method call:
				// ServiceCalls sc = new ServiceCalls(this._orchestration);
				// [Orchestration.PROPERTY = ]ServiceCalls.LOGACTNAME([PARAMETER]);
				// create new ServiceCalls instance
				statements.Add(
					new CodeVariableDeclarationStatement(
						typeRefSvcCalls, "sc",
						new CodeObjectCreateExpression(
							typeRefSvcCalls,
							new CodeFieldReferenceExpression(
								new CodeThisReferenceExpression(),
								"_orchestration"))));
				// create method invokation
				generateLogActServiceCallInvoke(
					Deployment.cServiceCallPrefix + logcap.LogicalActivityName,
					logcap, logact, op, verb,
					typeRefOutput, typeRefInput, statements);
			}
			return statements;
		}

		private void generateLogActServiceCallInvoke(
			string methodName,
			LogicalCapabilityActivity logcap, Repository.LogicalActivity logact,
			Repository.Operation op, Repository.Verb verb,
			CodeTypeReference typeRefOutput, CodeTypeReference typeRefInput,
			CodeStatementCollection statements)
		{
			CodeMethodInvokeExpression methCallSvc =
					new CodeMethodInvokeExpression(
					new CodeMethodReferenceExpression(
						new CodeVariableReferenceExpression("sc"),
						methodName));
			methCallSvc.Parameters.Add(
				new CodeArgumentReferenceExpression("context"));
			NamedBusinessObjectCollection subscriptions = logact.GetSubscribedBusinessObjects();
			if ( subscriptions.Count > 0 ) {
				// input parameters
				foreach ( NamedBusinessObject item in subscriptions ) {
					methCallSvc.Parameters.Add(
						new CodePropertyReferenceExpression(
							new CodeFieldReferenceExpression(
								new CodeThisReferenceExpression(), Deployment.cOrchestrationField),
								item.Name + Deployment.cBObjPropSuffix));
				}
			} else if ( typeRefInput != null ) {
				// add single input parameter
				if ( logact != null && logact.InputBusinessObject != null ) {
				} else if ( op != null && string.IsNullOrEmpty(op.InputBusinessObjectName) ) {
					methCallSvc.Parameters.Add(
						new CodePropertyReferenceExpression(
							new CodeFieldReferenceExpression(
								new CodeThisReferenceExpression(), Deployment.cOrchestrationField),
								op.InputBusinessObjectName + Deployment.cBObjPropSuffix));
				} else if ( verb != null && verb.InputBusinessObject != null ) {
					methCallSvc.Parameters.Add(
						new CodePropertyReferenceExpression(
							new CodeFieldReferenceExpression(
								new CodeThisReferenceExpression(), Deployment.cOrchestrationField),
								verb.InputBusinessObject.Name + Deployment.cBObjPropSuffix));
				}
			}
			if ( typeRefOutput != null && !( logcap is LogicalAsyncStartActivity ) ) {
				// set return value to workflow parameter and
				// add method invocation to logical activity method
				if ( logact != null && logact.OutputBusinessObject != null ) {
					statements.Add(
						new CodeAssignStatement(
							new CodePropertyReferenceExpression(
								new CodeFieldReferenceExpression(
									new CodeThisReferenceExpression(), Deployment.cOrchestrationField),
									logact.OutputBusinessObject.Name + Deployment.cBObjPropSuffix),
							methCallSvc));
				} else if ( op != null && op.OutputBusinessObjectName != null ) {
					statements.Add(
						new CodeAssignStatement(
							new CodePropertyReferenceExpression(
								new CodeFieldReferenceExpression(
									new CodeThisReferenceExpression(), Deployment.cOrchestrationField),
									op.OutputBusinessObjectName + Deployment.cBObjPropSuffix),
							methCallSvc));
				}
			} else {
				// add method invocation to logical activity method (with no return value)
				statements.Add(methCallSvc);
			}
		}
		#endregion

		#region Compile Workflow
		public List<string> saveFiles(string path)
		{
			List<string> files = new List<string>();

			writeStringToFile(Path.Combine(path, "Contracts.cs"), this.Workflow.CodeContracts);
			writeStringToFile(Path.Combine(path, "Data.cs"), this.Workflow.CodeData);
			writeStringToFile(Path.Combine(path, "IOrchestration.cs"), this.Workflow.CodeInterface);
			writeStringToFile(Path.Combine(path, "LogicalActivities.cs"), this.Workflow.CodeLogicalActivity);
			writeStringToFile(Path.Combine(path, "Mapping.cs"), this.Workflow.CodeMapping);
			writeStringToFile(Path.Combine(path, "Orchestration1.xoml"), this.Workflow.XOML);
			writeStringToFile(Path.Combine(path, "Orchestration1.xoml.cs"), this.Workflow.CodeBeside);
			writeStringToFile(Path.Combine(path, "Orchestration1.rules"), this.Workflow.Rules);
			writeStringToFile(Path.Combine(path, "Rules.cs"), this.Workflow.CodeRules);
			writeStringToFile(Path.Combine(path, "ServiceCalls.cs"), this.Workflow.CodeService);
			writeStringToFile(Path.Combine(path, "LocalService.cs"), this.Workflow.CodeLocalService);
			writeStringToFile(Path.Combine(path, "IWFInterface.cs"), this.Workflow.CodeOrchestrationInterface);

			// TODO: Remove if statement then enterprise mashups completed
			if ( this.Workflow.BuildType != WorkflowBuildType.WCF_WindowsForm ) {
				writeStringToFile(Path.Combine(path, "Service.cs"), this.Workflow.CodeHosting);
			}
			if ( configuration != null ) {
				string configPath = Path.Combine(path, "app.config");
				if ( configuration.FilePath == configPath ) {
					configuration.Save(ConfigurationSaveMode.Minimal, true);
				} else {
					configuration.SaveAs(configPath, ConfigurationSaveMode.Minimal, true);
				}
			}

			files.Add(Path.Combine(path, "Contracts.cs"));
			files.Add(Path.Combine(path, "Data.cs"));
			files.Add(Path.Combine(path, "IOrchestration.cs"));
			files.Add(Path.Combine(path, "LogicalActivities.cs"));
			files.Add(Path.Combine(path, "Mapping.cs"));
			files.Add(Path.Combine(path, "Orchestration1.xoml"));
			files.Add(Path.Combine(path, "Orchestration1.xoml.cs"));
			files.Add(Path.Combine(path, "Orchestration1.rules"));
			files.Add(Path.Combine(path, "Rules.cs"));
			files.Add(Path.Combine(path, "ServiceCalls.cs"));
			files.Add(Path.Combine(path, "LocalService.cs"));
			files.Add(Path.Combine(path, "IWFInterface.cs"));
			// TODO: Remove if statement then enterprise mashups completed
			if ( this.Workflow.BuildType != WorkflowBuildType.WCF_WindowsForm ) {
				files.Add(Path.Combine(path, "Service.cs"));
			}

			return files;
		}
		private void writeStringToFile(string filepath, string content)
		{
			using ( FileStream fs = File.Create(filepath) ) { }
			File.SetAttributes(filepath, FileAttributes.Temporary);
			File.WriteAllText(filepath, content);
		}
		#endregion

		#region Others
		private bool existsLogicalActivityMethod(string logactname)
		{
			bool exists = false;
			foreach ( CodeTypeMember member in _ctdLogActs.Members ) {
				CodeMemberMethod method = member as CodeMemberMethod;
				if ( method != null && method.Name == logactname ) {
					exists = true;
					break;
				}
			}
			return exists;
		}

		private void refreshCCU(object sender, EventArgs e)
		{
			// we dont want to do anything here
		}

		private void initLogicalActivitiesClassProperty(TypeProvider typeProvider)
		{
			CodeMemberProperty prop = Helpers.GetMember<CodeMemberProperty>(
				ccuBeside, this.FullClassName, "LogicalActivitiesClass");

			while ( prop == null ) {
				_memberCreation.CreateProperty(this.FullClassName,
							   "LogicalActivitiesClass",
							   typeProvider.GetType(this.Namespace + ".LogicalActivities"),
							   null,
							   true,
							   false,
							   false,
							   null,
							   true);
				prop = Helpers.GetMember<CodeMemberProperty>(
					ccuBeside, this.FullClassName, "LogicalActivitiesClass");
			}
			prop.GetStatements.Clear();

			Type typeLogActs = typeProvider.GetType(this.Namespace + ".LogicalActivities");

			prop.GetStatements.Add(
				new CodeVariableDeclarationStatement(
					typeLogActs,
					"la",
					new CodeCastExpression(
						typeLogActs,
						new CodeMethodInvokeExpression(
							new CodeBaseReferenceExpression(),
							"GetValue",
							new CodeFieldReferenceExpression(
								new CodeTypeReferenceExpression(this.FullClassName),
								"LogicalActivitiesClassProperty")))));
			prop.GetStatements.Add(
				new CodeConditionStatement(
					new CodeBinaryOperatorExpression(
						new CodeVariableReferenceExpression("la"),
						CodeBinaryOperatorType.ValueEquality,
						new CodePrimitiveExpression(null)),
					new CodeAssignStatement(
						new CodeVariableReferenceExpression("la"),
						new CodeObjectCreateExpression(
							typeLogActs,
							new CodeThisReferenceExpression())),
					new CodeExpressionStatement(new CodeMethodInvokeExpression(
						new CodeBaseReferenceExpression(),
						"SetValue",
						new CodeFieldReferenceExpression(
							new CodeTypeReferenceExpression(this.FullClassName),
							"LogicalActivitiesClassProperty"),
						new CodeVariableReferenceExpression("la")))));
			prop.GetStatements.Add(
				new CodeMethodReturnStatement(
					new CodeVariableReferenceExpression("la")));

		}

		private T getService<T>() where T : class
		{
			return _serviceContainer.GetService(typeof(T)) as T;
		}

		private void generateSourceCode()
		{
			ITaskListService taskList = (ITaskListService)this.GetService(typeof(ITaskListService));

			if ( taskList != null ) taskList.Clear(this.Workflow, cTaskListSourceNameSave);

			try {
				using ( new WaitMouse() ) {
					// Flush CS code
					CSharpCodeProvider provider = new CSharpCodeProvider();
					// Just chooses some formatting options, like four space indenting
					CodeGeneratorOptions options = new CodeGeneratorOptions();
					options.BlankLinesBetweenMembers = true;
					options.BracingStyle = "C";
					options.ElseOnClosing = true;
					options.IndentString = "\t";

					// save CodeBeside
					using ( StringWriter sw = new StringWriter() ) {
						provider.GenerateCodeFromCompileUnit(this.CodeBeside, sw, options);
						this.Workflow.CodeBeside = sw.ToString();
					}
					// save LogicalActivities
					using ( StringWriter sw = new StringWriter() ) {
						provider.GenerateCodeFromCompileUnit(this.CodeLogicalActivities, sw, options);
						this.Workflow.CodeLogicalActivity = sw.ToString();
					}
					// save Services
					using ( StringWriter sw = new StringWriter() ) {
						provider.GenerateCodeFromCompileUnit(this.CodeServices, sw, options);
						this.Workflow.CodeService = sw.ToString();
					}
					// save Mapping
					using ( StringWriter sw = new StringWriter() ) {
						provider.GenerateCodeFromCompileUnit(this.CodeMapping, sw, options);
						this.Workflow.CodeMapping = sw.ToString();
					}
					// save CodeRules
					using ( StringWriter sw = new StringWriter() ) {
						provider.GenerateCodeFromCompileUnit(this.CodeRules, sw, options);
						this.Workflow.CodeRules = sw.ToString();
					}
					// save Data
					using ( StringWriter sw = new StringWriter() ) {
						provider.GenerateCodeFromCompileUnit(this.CodeData, sw, options);
						this.Workflow.CodeData = sw.ToString();
					}
					// save Contracts
					using ( StringWriter sw = new StringWriter() ) {
						provider.GenerateCodeFromCompileUnit(this.CodeContracts, sw, options);
						this.Workflow.CodeContracts = sw.ToString();
					}
					// save Interface
					using ( StringWriter sw = new StringWriter() ) {
						provider.GenerateCodeFromCompileUnit(this.CodeInterface, sw, options);
						this.Workflow.CodeInterface = sw.ToString();
					}
					// save Local Service
					using ( StringWriter sw = new StringWriter() ) {
						provider.GenerateCodeFromCompileUnit(this.CodeLocalService, sw, options);
						this.Workflow.CodeLocalService = sw.ToString();
					}
					// save Host Service
					using ( StringWriter sw = new StringWriter() ) {
						provider.GenerateCodeFromCompileUnit(this.CodeHostService, sw, options);
						this.Workflow.CodeHosting = sw.ToString();
					}
					// save Orchestration Interface
					using ( StringWriter sw = new StringWriter() ) {
						provider.GenerateCodeFromCompileUnit(this.CodeWorkflowInterface, sw, options);
						this.Workflow.CodeOrchestrationInterface = sw.ToString();
					}

					// Flush the rules file
					if ( this.tempRulesStream != null ) {
						this.Workflow.Rules = this.tempRulesStream.ToString();
					}
					// save used rule ids
					this.Workflow.SetRuleIDs(this.RuleIDs);
					// set code namespace
					this.Workflow.ExtendedProperties.NamespaceCode = this.Namespace;
				}
			} catch ( Exception ex ) {
				if ( taskList == null ) {
					if ( this.ShowErrorMessageBox ) {
						MessageBox.Show(ex.Message, "Save Error!", MessageBoxButtons.OK, MessageBoxIcon.Error);
					}
				} else {
					taskList.Add(this.Workflow, TaskItemType.Error, TaskStatus.None, Workflow, ex.Message, cTaskListSourceNameSave);
				}
			}
		}
		#endregion

		#endregion

		#endregion

		#region IMemberCreationCodeService Members

		Activity IMemberCreationCodeService.RootActivity
		{
			get
			{
				if ( this.Workflow != null ) {
					return Helpers.GetRootActivity(this.Workflow);
				}
				return null;
			}
		}

		CodeCompileUnit IMemberCreationCodeService.CodeXaml
		{
			get { return this.CodeXaml; }
		}

		CodeCompileUnit IMemberCreationCodeService.CodeBeside
		{
			get { return this.CodeBeside; }
		}

		string IMemberCreationCodeService.ClassName
		{
			get
			{
				return this.ClassName;
			}
			set
			{
				this.Workflow.Name = value;
			}
		}

		string IMemberCreationCodeService.Namespace
		{
			get
			{
				return this.Namespace;
			}
			set
			{
				this.Workflow.ExtendedProperties.NamespaceCode = value;
			}
		}

		#endregion
	}

}
